object main {
def main(args: Array[String]) = {
val x = Option(2)
val y = None // works with: Option.empty[Int]
val z = Option(5)
val result1 = for {
x <- x
y <- y
z <- z
} yield {
(x, y, z, x + y + z, x * y * z)
}
println(result1)
}
}
This code yields an exception:
example.scala:14: 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)
(x, y, z, x + y + z, x * y * z)
If we use val y = Option.empty[Int]
instead of val y = None
, it works in the sense that result1
contains None
.
But why are there any restrictions on the function *
? We don't get (2, None, 5, None, None)
anyway. I assumed the step would be skipped if one value was None
, so why must *
unambiguously refer to a definition?
The error happens because y
has type None
which extends Option[Nothing]
.
In the for comprehension, the inner y
thus has a Nothing
type and you cannot apply *
to Nothing
.
The error goes away if you explicitly type (outer) y
to Option[Int]
:
val y: Option[Int] = None
When you say:
assumed the step would be skipped if one value was
None
This is true at runtime, but at compile time the compiler only sees a combination of Option[Int]
and Option[Nothing]
.