Scala 2.10似乎更新了对Either的理解。 在2.10:
scala> val a = Right(5)
a: scala.util.Right[Nothing,Int] = Right(5)
scala> for {aa: Int <- a.right} yield {aa}
<console>:9: error: type mismatch;
found : Int => Int
required: scala.util.Either[Nothing,Int] => ?
for {aa: Int <- a.right} yield {aa}
^
在2.9.3中,以上是可以的。
scala> val a = Right(5)
a: Right[Nothing,Int] = Right(5)
scala> for {aa: Int <- a.right} yield {aa}
res0: Product with Serializable with Either[Nothing,Int] = Right(5)
只需在2.10中删除aa的类型即可轻松修复。但我想知道为什么行为会在2.9和2.10之间发生变化。
答案 0 :(得分:6)
这似乎是由于open bug即使不需要withFilter
也是如此。为了解释它,一些简短的介绍:
在2.10
下面编译,-Xprint:typer
给出
for {aa <- a.right} yield {aa}
Temp.this.a.right.map[Int](((aa: Int) => aa))
//for below
for {aa:Int <- a.right} yield {aa}
a.right.filter[Nothing](((check$ifrefutable$1: Int) => (check$ifrefutable$1: Int @unchecked) match {
case (aa @ (_: Int)) => true
case _ => false
})).map[B](((aa: Int) => aa))
这显然是第二种情况的错误。因为简而言之,您doing Option[scala.util.Either[Nothing,Int]].map((aa:Int) => aa)
这是一个错误,因为它需要的地图超过Either
而不是Int
。
在 Scala 2.9.3 中,对于上述两种情况,它都给出了:
a.right.map[Int](((aa: Int) => aa))
在2.10
中添加with-filter
子句。来自for-comprehension specs:
翻译方案如下。在第一步中,每个发电机 p&lt; - e,其中p 不可反驳,因为e的类型被替换为
p&lt; - e.withFilter {case p =&gt;真正; case _ =&gt;假}
在您的第一种情况下,p
为Irrefutable(规格中为Point-1),因此未添加withFilter。在第二种情况下,p
为Irrefutable(第2点,因此不应添加withFilter
。但它确实存在错误。
类似于:why does filter have to be defined for pattern matching in a for loop in scala?