要么理解2.9和2.10中的不同行为

时间:2014-10-30 06:26:55

标签: scala

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之间发生变化。

1 个答案:

答案 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;假}

在您的第一种情况下,pIrrefutable(规格中为Point-1),因此未添加withFilter。在第二种情况下,pIrrefutable(第2点,因此不应添加withFilter。但它确实存在错误。

类似于:why does filter have to be defined for pattern matching in a for loop in scala?