For-Comprehension Desugaring
Desugaring is the rewriting of a for-comprehension into plain flatMap, map and withFilter calls. The compiler performs this rewriting before the program runs.
One generator becomes map
A for-comprehension with one generator and a yield is just a map. Both lines print the same doubled list.
@main def main(): Unit =
println(List(1, 2, 3).map(x => x * 2))
println(for x <- List(1, 2, 3) yield x * 2)Two generators become flatMap and map
The first generator becomes a flatMap and the second becomes a map inside it. Both lines print the same four sums.
@main def main(): Unit =
println(List(1, 2).flatMap(x => List(10, 20).map(y => x + y)))
println(for x <- List(1, 2); y <- List(10, 20) yield x + y)A guard becomes withFilter
An if guard inside a for-comprehension becomes a withFilter call. Both lines print only the doubled even numbers.
@main def main(): Unit =
println(List(1, 2, 3, 4).withFilter(x => x % 2 == 0).map(x => x * 10))
println(for x <- List(1, 2, 3, 4) if x % 2 == 0 yield x * 10)Example
@main def main(): Unit =
println(List(1, 2, 3).flatMap(x => List(10, 20).withFilter(y => x + y > 21).map(y => x + y)))
println(for x <- List(1, 2, 3); y <- List(10, 20); if x + y > 21 yield x + y)Key points
- For-comprehension: A for-comprehension is short syntax for chaining steps over values in containers.
- Map: A map step transforms each value inside a container and keeps the container shape.
- FlatMap: A flatMap step runs a step that returns a container and then flattens the nested result.
- WithFilter: A withFilter step keeps only the values that pass a test.
- Yield: The yield part says what value each surviving combination produces.
In this example, the first line writes the desugared form by hand with flatMap, withFilter and map. The second line writes the same program as a for-comprehension with two generators and a guard. Both lines print the same two sums.
Note
Scala rewrites a for-comprehension mechanically, so the rewritten form is not a different program with different behaviour.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What does an if guard inside a for-comprehension become?