为什么在不带参数类型的情况下使用 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 理解如何与 Left
和 Right
一起工作?为什么第一个和最后一个案例在我的示例中不起作用?
这是因为没有共同的推断类型,并且您没有为所有 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
我在尝试练习 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 理解如何与 Left
和 Right
一起工作?为什么第一个和最后一个案例在我的示例中不起作用?
这是因为没有共同的推断类型,并且您没有为所有 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