gpt4 book ai didi

scala - 在scala中如何翻译具有多个monad的for表达式?

转载 作者:行者123 更新时间:2023-12-04 04:06:22 24 4
gpt4 key购买 nike

我正在阅读“Scala 2nd Edition中的编程”,并且从我参加的Haskell类(class)中对monad有了一些了解。但是,我不明白为什么以下代码“神奇地”起作用:

scala> val a: Option[Int] = Some(100)
a: Option[Int] = Some(100)

scala> val b = List(1, 2, 3)
b: List[Int] = List(1, 2, 3)

for ( y <- b; x <- a ) yield x;
res5: List[Int] = List(100, 100, 100)

我不理解上面的内容,因为根据本书的第23.4章, for表达式被翻译成类似以下内容:
b flatMap ( y =>
a map ( x => x )
)

我不知道为什么上面的代码可以编译,因为 y => a map (x => x)Int => Option[Int]类型,而 b.flatMap需要 Int => List[Something]

另一方面,以下代码不会编译(这很好,否则我会更迷失):
scala> for ( x <- a; y <- b ) yield y;
<console>:10: error: type mismatch;
found : List[Int]
required: Option[?]
for ( x <- a; y <- b ) yield y;
^

那么第一个示例的神奇之处是什么?

最佳答案

[…] b.flatMap expects a Int => List[Something].



事实并非如此:它期望的是 Int => GenTraversableOnce[Something]。 (请参阅 http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List,并在页面上搜索 flatMap。) List[A]是继承的 GenTraversableOnce[A]的子类型。由于 Int => List[Something]的结果 R的协方差(定义为 Function1),因此可以对 trait Function1[-T1, +R]类型的函数进行求位。
Option[A]不是 GenTraversableOnce[A],但是 Option's companion object中存在一个隐式转换: implicit def option2Iterable[A](xo: Option[A]): Iterable[A]Iterable[A]GenTraversableOnce[A]的子类型。因此,表达式将扩展为
b flatMap ( y =>
option2Iterable(a map ( x => x ))
)

On the other hand, the following code does NOT compile […]



相比之下,这是因为 a.flatMap更具体:它确实需要 Int => Option[Something]。 (请参阅 http://www.scala-lang.org/api/current/index.html#scala.Option,并在页面上搜索 flatMap。)这是有道理的,因为 Option[Something]只能容纳一个值,因此您无法将任意 GenTraversableOnce[Something]展平到其中。可以成功地压平成 Option[Something]的唯一东西是另一个 Option[Something]

关于scala - 在scala中如何翻译具有多个monad的for表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15048240/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com