for {
a <- Some(1)
b <- Some(2)
} yield (a, b)
returns Some((1, 2))
for {
a <- Right(1).right
b <- Left(2).left
} yield (a, b)
returns Left((1, 2))
Now I want to decompose tuples in the for comprehension.
for {
(a, b) <- Some((1, 2))
(c, d) <- Some((3, 4))
} yield (a, b, c, d)
returns Some((1, 2, 3, 4))
for {
(a, b) <- Right((1, 2)).right
(c, d) <- Left((3, 4)).left
} yield (a, b, c, d)
fails to compile:
error: constructor cannot be instantiated to expected type;
found : (T1, T2)
required: scala.util.Either[Nothing,(Int, Int)]
(a, b) <- Right((1, 2)).right
error: constructor cannot be instantiated to expected type;
found : (T1, T2)
required: scala.util.Either[(Int, Int),Nothing]
Why doesn't this last example work? What is the difference?
This is a bug:
withFilter()
is called (some documentation references filter()
, but that was changed in 2.8), which messes with the type inference.
withFilter()
is used for things like for(a <- b if c)
, though according to the 6.19 it shouldn't be used in this case.
This latter bug is captured in SI-1336: spec requires type checking of for-comprehension to consider refutability, which has been open for seven years (2008).
Perhaps some future generation will find the fix.
See why does filter have to be defined for pattern matching in a for loop in scala?