如果`for`中的至少一个组件为None,则for-comprehension返回None。

Jac*_* P. 1 scala for-comprehension flatmap

我很难理解Scala中使用for-compression的机制。例如,如果我有

val x = for {
  i <- Option(1)
  j <- Option(2)
  k <- Option(3)
} yield (i,j,k)
Run Code Online (Sandbox Code Playgroud)

xx: Option[(Int, Int, Int)] = Some((1,2,3))。但是,例如,如果组件中的至少一个为“无”,

val x = for {
  i <- Option(1)
  j <- Option(2)
  k <- None
} yield (i,j,k)
Run Code Online (Sandbox Code Playgroud)

然后x是的x: Option[(Int, Int, Nothing)] = None,而我实际上希望看到这样的东西:x: Option[(Int, Int, Nothing)] = Some((1,2,None))

我已经检查了从Scala的官方文档常见问题在那里特别指出for-comprehension的组合flatmapmap。但我还是有难度的理解是,xNone

我想我错过了一些重要的概念flatmapmap区别。

Tza*_*har 5

第一个具有理解力的“减糖”为:

val x = Option(1).flatMap(
  i => Option(2).flatMap(
    j => Option(3).map(
      k => (i, j, k)
    )
  )
)
Run Code Online (Sandbox Code Playgroud)

如您所见-使用具有其值(如果存在)并返回3元组(在第二个选项上使用类似的操作)的函数,第一个选项是平面映射的。无论该函数是什么-整个表达式的形式均为:

val x = Option(1).flatMap(f)
Run Code Online (Sandbox Code Playgroud)

现在,如果我们将其替换Option(1)None(如您在第二个表达式中所做的那样),我们显然会得到None

val x = None.flatMap(f) // None, for any f
Run Code Online (Sandbox Code Playgroud)

您期望的结果(Some((None, 2, 3)))不太有用-因为对于不同的输入它将具有不同的类型:是(Option[Int], Int, Int)吗?还是(Int, Int, Int)?还是(Option[Int], Option[Int], Option[Int])?确实是的唯一通用类型(None, 2, 3)(1, None, 3)并且(1, 2, None)不是那么有用(Any, Any, Any)