为什么在不带参数类型的情况下使用 Left 时会出现模糊引用错误?

Why ambiguous reference error while using Left without parameters type?

我在尝试练习 scala 面试问题时发现“对重载定义的模糊引用”。

我试图找到导致编译错误的以下代码块的结果:

代码:

for {
  v1 <- Left[Int,Int](1)
  v2 <- Right(2)
  v3 <- Right(3)
  v4 <- Left(4)
} yield v1 + v2 + v3 + v4

错误:

<pastie>:17: error: ambiguous reference to overloaded definition,
both method + in class Int of type (x: Char)Int
and  method + in class Int of type (x: Byte)Int
match argument types (Nothing)
} yield v1 + v2 + v3 + v4
                     ^

当我们仅在 v1 字段而不是 v4[ 上指定类型时,为什么 Scala 编译器会给出 模糊引用错误 =41=] ?

我还在 v1 和 v4 中尝试了具有不同参数类型的以下版本并且它有效!

for {
  v1 <- Left[String,Int]("1")
  v2 <- Right(2)
  v3 <- Right(3)
  v4 <- Left[Int, Int](4)
} yield v1 + v2 + v3 + v4

输出为:

res20: scala.util.Either[Any,Int] = Left(1)

我尝试了另一个版本也导致了错误:

for {
  v1 <- Left(1)
  v2 <- Right(2)
  v3 <- Right(3)
  v4 <- Left(4)
} yield v1 + v2 + v3 + v4

输出:

<console>:17: error: value + is not a member of Nothing
       } yield v1 + v2 + v3 + v4

这里的 for 理解如何与 LeftRight 一起工作?为什么第一个和最后一个案例在我的示例中不起作用?

这是因为没有共同的推断类型,并且您没有为所有 Either 指定类型。

所以

scala> for (v1 <- Right(2)) yield v1
res13: scala.util.Either[Nothing,Int] = Right(2)

解决办法是给他们通用的类型

for {
  v1 <- Left[Int,Int](1)
  v2 <- Right[Int,Int](2)
  v3 <- Right[Int,Int](3)
  v4 <- Left[Int,Int](4)
} yield v1 + v2 + v3 + v4

这给出了 Left(1)。这个结果是有道理的,因为 Either 是右偏的,并且作为 flatMap.

的理解

根据文档: "要么是右偏的,这意味着 Right 被假定为要操作的默认情况。如果是 Left,像 map,flatMap,...这样的操作 return Left 值不变"
https://www.scala-lang.org/api/2.12.0/scala/util/Either.html