On the subject of desugaring for
expressions with map
, flatMap
and withFilter
, the book Programming In Scala 3rd Ed. says (in the chapter For Expression Revisited)
The translation of
for
expressions happens before type checking. This allows for maximum flexibility because the only requirement is that the result of expanding afor
expression type checks.
However, in the REPL,
for (x: Int <- List("a", "b")) yield x
gives
<console>:12: error: scrutinee is incompatible with pattern type;
found : Int
required: String
for(x: Int <- List("a", "b")) yield x
^
and similarly,
for(x <- List("a", "b")) yield math.pow(x, 2)
gives
<console>:12: error: type mismatch;
found : String
required: Double
for(x <- List("a", "b")) yield math.pow(x, 2)
^
This seems to me to contradict what the book states, in that it appears type checking is happening before desugaring. Perhaps ...
I believe your second suggestion is correct. Both of these type errors happen after translation, but it would be quite annoying if the compiler pointed you at some generated code when it gave you that error. Imagine it instead gave this message:
<console>:12: error: type mismatch;
found : String
required: Double
List("a", "b").map(x => math.pow(x, 2))
^
Then you have to sit there and ponder what this code is - you didn't write any calls to map
or any anonymous function like that. And it would be 10x worse if the for-comprehension was more complicated, and resulted in multiple nested flatMap
s and withFilter
s and stuff. So instead it points you to the pre-transformed version you actually wrote.