Scala 中无法解释的理解结果
inexplicable for-comprehension result in Scala
我理解 for-expression 被翻译成 map 和 flatMap。但是我发现了一些我无法解释的事情,需要你的帮助。这里有两个玩具示例:
for {
None <- List(Option(1),None)
} yield 0
//res0: List[Int] = List(0, 0)
Q1: 为什么 Some(1) 映射到 0 ?我期待列表(0),
更新1:
感谢@marios 的评论,这个更奇怪。
for(None <- List(Some(1), None) ) yield None
returns List(Some(1), None)
。
更新2:
有人说它是一个变量,但在 IDE 中,它实际上链接到一个 None
对象。
我使用 IntelliJ 将上面的 for-expression 自动翻译成 map-expression:
List(Option(1), None).map { case None => 0 }
//scala.MatchError: Some(1)
Q2: 这个映射表达式的错误是预期的,而第一个问题中的 for 表达式没有给我这个错误。为什么他们得到不同的计算?
这两个return相同的结果。
for(None <- List(Some(1), None) ) yield None
for(x <- List(Some(1), None) ) yield x
看来 None <-
不是丢弃值的有效方法。相反,它只是创建一个临时变量来屏蔽 None
对象。
这似乎是 Scala 编译器中的错误。 Scala Language Specification 声明:"In a first step, every generator p <- e
, where p
is not irrefutable for the type of e
is replaced by p <- e.withFilter { case p => true; case _ => false }
",然后是 "a for comprehension for (p <- e) yield e′
is translated to e.map { case p => e′ }
."
这意味着您的示例 for { None <- List(Option(1), None) } yield 0
应翻译为
List(Option(1),None).withFilter { case None => true; case _ => false }.map{case None => 0}
如您所料,计算结果为 List(0)
。
我理解 for-expression 被翻译成 map 和 flatMap。但是我发现了一些我无法解释的事情,需要你的帮助。这里有两个玩具示例:
for {
None <- List(Option(1),None)
} yield 0
//res0: List[Int] = List(0, 0)
Q1: 为什么 Some(1) 映射到 0 ?我期待列表(0),
更新1:
感谢@marios 的评论,这个更奇怪。
for(None <- List(Some(1), None) ) yield None
returns List(Some(1), None)
。
更新2:
有人说它是一个变量,但在 IDE 中,它实际上链接到一个 None
对象。
我使用 IntelliJ 将上面的 for-expression 自动翻译成 map-expression:
List(Option(1), None).map { case None => 0 }
//scala.MatchError: Some(1)
Q2: 这个映射表达式的错误是预期的,而第一个问题中的 for 表达式没有给我这个错误。为什么他们得到不同的计算?
这两个return相同的结果。
for(None <- List(Some(1), None) ) yield None
for(x <- List(Some(1), None) ) yield x
看来 None <-
不是丢弃值的有效方法。相反,它只是创建一个临时变量来屏蔽 None
对象。
这似乎是 Scala 编译器中的错误。 Scala Language Specification 声明:"In a first step, every generator p <- e
, where p
is not irrefutable for the type of e
is replaced by p <- e.withFilter { case p => true; case _ => false }
",然后是 "a for comprehension for (p <- e) yield e′
is translated to e.map { case p => e′ }
."
这意味着您的示例 for { None <- List(Option(1), None) } yield 0
应翻译为
List(Option(1),None).withFilter { case None => true; case _ => false }.map{case None => 0}
如您所料,计算结果为 List(0)
。