Pol*_*ase 1 scala for-comprehension
在下面的代码中,版本1给出了正确的结果.我在V2中做了一个小变化.无值已经消失,这是好的,因为这是For Expression的工作方式.但是什么原因导致V2中的yield输出不再尊重myList.lift()返回的数据类型,这是一个Option(如V1所示)?
val myList = List(12, 34, "ABC")
Run Code Online (Sandbox Code Playgroud)
版本1
for { i <- (0 to 3).toList } yield myList.lift(i)
// res1: List[Option[Any]] = List(Some(12), Some(34), Some(ABC), None)
Run Code Online (Sandbox Code Playgroud)
版本2
for {
i <- (0 to 3).toList
x <- myList.lift(i)
} yield x
// res2: List[Any] = List(12, 34, ABC)
Run Code Online (Sandbox Code Playgroud)
贬低第一个案例:
// desugar for comprehension:
(0 to 3).toList.map(
i => myList.lift(i))
Run Code Online (Sandbox Code Playgroud)
贬低第二种情况:
// desugar for comprehension:
(0 to 3).toList.flatMap(
i => myList.lift(i).map(
x => x))
// remove .map(x => x):
(0 to 3).toList.flatMap(
i => myList.lift(i))
// desugar flatMap:
(0 to 3).toList.map(
i => myList.lift(i)).flatten
Run Code Online (Sandbox Code Playgroud)
第二种情况简化为第一种情况,最后是a .flatten,这解释了结果的不同:res2 = res1.flatten.
Scala可以Option视为一个序列:
Some(foo) --> Seq(foo)
None --> Seq()
Run Code Online (Sandbox Code Playgroud)
这.flatten只是使序列序列变平.
如果你对这些类型感到好奇:
scala.collection.Seq.flatten 要求'inner'类型具有隐式转换 GenTraversableOnce[T]Option[T]到Iterable[T]Iterable[T] <: GenTraversableOnce[T]将<-在x <- myList.lift(i)没有按"吨只是一个变量分配给一个值,'得到一个值超出’ myList.lift(i)当你'得到一个值超出’了Option[T],你得到foo的Some(foo)并没有什么的None.'得到什么’是指yield没有按" T运行对于a来说None,所以没有任何东西出现在"迭代"的结果中i = 3.
如果您想了解这个"获取值出来的",也就是为定义的概念Seq,Option和许多其他类型在Scala中,它是任何单子定义.