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)
x是x: 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的组合flatmap和map。但我还是有难度的理解是,x是None。
我想我错过了一些重要的概念flatmap和map区别。
第一个具有理解力的“减糖”为:
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)。