为什么使用元组的Scala表达式无法编译?

Lac*_*lan 7 scala compiler-errors

使用Scala 2.8.1,编译:

val t = (40, 2)

println(for ((i, j) <- List(t)) yield i + j)

val e: Either[String, (Int, Int)] = Right(t)
println(e.right.map {
  case (i, j) => i + j
})
println(for ((i, j) <- e.right) yield i + j)
Run Code Online (Sandbox Code Playgroud)

给出这个:

test.scala:9: error: constructor cannot be instantiated to expected type;
 found   : (T1, T2)
 required: Either[Nothing,(Int, Int)]
println(for ((i, j) <- e.right) yield i + j)
Run Code Online (Sandbox Code Playgroud)

根据Scala中的Programming,for表达式应该等同于map/case表达式,但只有后者才能编译.我做错了什么,我应该怎么做?

Dan*_*ral 11

其实,这不是相当正在发生转换.您可以参考此答案以获得更完整的指南,但即使在那里也没有明确提及此案例.

通过模式匹配进行理解可以过滤不匹配的情况.例如,

for((i, j) <- List((1, 2), 3)) yield (i, j)
Run Code Online (Sandbox Code Playgroud)

将返回List((1, 2)): List[(Any, Any)],因为withFilter第一次调用.现在,Either似乎没有withFilter,所以它将使用filter,这里是理解的实际翻译:

e.right.filter { case (i, j) => true; case _ => false }.map { case (i, j) => i + j }
Run Code Online (Sandbox Code Playgroud)

这给出了完全相同的错误.问题是e.right返回RightProjection,但filterRightProjection[A, B]回报Option[Either[Nothing, B]].

原因是没有"空" Either(或RightProjection)这样的东西,所以它需要将其结果封装在一个Option.

说了这么多,看看for-comprehension水平真是令人惊讶.我认为正确的做法是filter返回某种过滤后的投影.