Why does this construction cause a Type Mismatch error in Scala?
for (first <- Some(1); second <- List(1,2,3)) yield (first,second)
<console>:6: error: type mismatch;
found : List[(Int, Int)]
required: Option[?]
for (first <- Some(1); second <- List(1,2,3)) yield (first,second)
If I switch the Some with the List it compiles fine:
for (first <- List(1,2,3); second <- Some(1)) yield (first,second)
res41: List[(Int, Int)] = List((1,1), (2,1), (3,1))
This also works fine:
for (first <- Some(1); second <- Some(2)) yield (first,second)
For comprehensions are converted into calls to the
maporflatMapmethod. For example this one:becomes that:
Therefore, the first loop value (in this case,
List(1)) will receive theflatMapmethod call. SinceflatMapon aListreturns anotherList, the result of the for comprehension will of course be aList. (This was new to me: For comprehensions don’t always result in streams, not even necessarily inSeqs.)Now, take a look at how
flatMapis declared inOption:Keep this in mind. Let’s see how the erroneous for comprehension (the one with
Some(1)) gets converted to a sequence of map calls:Now, it’s easy to see that the parameter of the
flatMapcall is something that returns aList, but not anOption, as required.In order to fix the thing, you can do the following:
That compiles just fine. It is worth noting that
Optionis not a subtype ofSeq, as is often assumed.