Scala 如果“for”中至少有一个组件为None,则for comprehension返回None

Scala 如果“for”中至少有一个组件为None,则for comprehension返回None,scala,flatmap,for-comprehension,Scala,Flatmap,For Comprehension,我很难理解Scala中用于压缩的机制。 例如,如果我有 val x = for { i <- Option(1) j <- Option(2) k <- Option(3) } yield (i,j,k) 然后x是x:Option[(Int,Int,Nothing)]=None,而我实际上希望看到这样的东西:x:Option[(Int,Int,Nothing)]=Some((1,2,None)) 我已经检查了地图,其中特别说明了理解的是平面地图和地图的组合。但是我

我很难理解Scala中用于压缩的机制。 例如,如果我有

val x = for {
  i <- Option(1)
  j <- Option(2)
  k <- Option(3)
} yield (i,j,k)
然后
x
x:Option[(Int,Int,Nothing)]=None
,而我实际上希望看到这样的东西:
x:Option[(Int,Int,Nothing)]=Some((1,2,None))

我已经检查了地图,其中特别说明了理解的
平面地图
地图
的组合。但是我仍然很难理解
x
None


我想我错过了一些关于
flatmap
map
差异的重要概念。

第一个理解“desugars”的概念是:

如您所见,第一个选项是平面映射的,它使用一个函数获取其值(如果存在)并返回一个3元组(在第二个选项上使用类似的操作)。不管函数是什么-整个表达式的形式如下:

val x = Option(1).flatMap(f)
现在,如果我们将
选项(1)
替换为
(正如您在第二个表达式中所做的那样),我们显然会得到

val x = None.flatMap(f) // None, for any f

您期望的结果(
Some((None,2,3))
)并不太有用,因为它对于不同的输入有不同的类型:它会是
(Option[Int],Int,Int)
?或者
(Int,Int,Int)
?或者
(选项[Int],选项[Int],选项[Int])
?实际上,
(None,2,3)
(1,None,3)
(1,2,None)
的唯一常见类型是不太有用的
(Any,Any,Any)
,第一个将“desugars”理解为:

如您所见,第一个选项是平面映射的,它使用一个函数获取其值(如果存在)并返回一个3元组(在第二个选项上使用类似的操作)。不管函数是什么-整个表达式的形式如下:

val x = Option(1).flatMap(f)
现在,如果我们将
选项(1)
替换为
(正如您在第二个表达式中所做的那样),我们显然会得到

val x = None.flatMap(f) // None, for any f

您期望的结果(
Some((None,2,3))
)并不太有用,因为它对于不同的输入有不同的类型:它会是
(Option[Int],Int,Int)
?或者
(Int,Int,Int)
?或者
(选项[Int],选项[Int],选项[Int])
?实际上,
(None,2,3)
(1,None,3)
(1,2,None)
的唯一常见类型是{ab}
的不太有用的
(Any,Any,Any)
。另外,
None.flatMap(f)==None
&
None.map(f)==None
。因此,正如您所说,如果至少有一个元素是None,那么for的结果将是None(这就是为什么说None像短路一样,因为它将忽略后面的所有内容)另外,
Option[(Int,Int,Int)]=Some((None,2,3))
是错误的,因为您说过元组的第一个元素将是
Int
,并且您向它传递了一个None(它具有type
Option[Nothing]
),所以它不会进行类型检查。希望它有帮助:)
对于{abb}
。另外,
None.flatMap(f)==None
&
None.map(f)==None
。因此,正如您所说,如果至少有一个元素是None,那么for的结果将是None(这就是为什么说None像短路一样,因为它将忽略后面的所有内容)另外,
Option[(Int,Int,Int)]=Some((None,2,3))
是错误的,因为您说过元组的第一个元素将是
Int
,并且您向它传递了一个None(它具有type
Option[Nothing]
),所以它不会进行类型检查。希望它能有所帮助:)有趣的一点是:类型的有用性,但我更倾向于将其视为跨集合的一致性考虑(将
Option
视为一个集合)。考虑<代码>理解< <代码> > <代码>列表>代码> {<代码> > {有趣点RE:类型有用性,但我倾向于更多地考虑跨集合的一致性(使用<代码>选项>代码>作为集合)考虑“<代码>理解< <代码> > <代码>列表>代码> {<代码> > {i