为什么在使用Left without parameters类型时出现不明确的引用错误



我发现"对重载定义的模糊引用";在尝试练习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编译器会给不明确的引用错误

我还在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

对于理解,在这里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

从而得到CCD_ 4。这一结果是有意义的,因为Either是右偏的,并且对于作为flatMap的理解来说。

根据文件:"任意一个都是右偏的,这意味着right被认为是操作的默认情况。如果是Left,则map、flatMap等操作。。。返回Left值不变">
https://www.scala-lang.org/api/2.12.0/scala/util/Either.html

最新更新