Scala For-Comprehensions
A for-comprehension is a short way to build a new collection from one or more collections. It reads like a loop but it produces a value.
A for-comprehension builds a new list
One generator takes each number in turn. Doubling each one gives a list of doubled numbers.
@main def main(): Unit =
val nums = List(1, 2, 3)
val doubled = for x <- nums yield x * 2
println(doubled)Two generators combine every pair
The guard keeps only pairs where the first number is above 1. The kept sums appear in pair order.
@main def main(): Unit =
val pairs = for x <- List(1, 2, 3); y <- List(10, 20) if x > 1 yield x + y
println(pairs)For-syntax and flatMap with map give the same list
The for version and the flatMap and map version build the same pairs in the same order. Both lists match exactly.
@main def main(): Unit =
val a = for x <- List(1, 2); y <- List(10, 20) yield x + y
val b = List(1, 2).flatMap(x => List(10, 20).map(y => x + y))
println(a)
println(b)Example
@main def main(): Unit =
val sums = for x <- List(1, 2, 3); y <- List(4, 5) if (x + y) % 2 == 0 yield x * 10 + y
println(sums)
println(sums.length)Key points
- For-comprehension: a for expression with generators that yields a new collection.
- Generator: one step that takes each value from a collection in turn.
- Yield: the word that turns the values from the generators into a result collection.
- Guard: an if condition inside the for that keeps only matching combinations.
- Desugaring: the compiler turns a for-comprehension into flatMap and map calls.
In this example, the for-comprehension pairs each number from the first list with each number from the second list. The guard keeps only pairs whose sum is even, and each kept pair is coded as ten times the first number plus the second. Three pairs survive.
Note
a for without yield runs actions and returns nothing useful. A for with yield builds a value.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
Which code is the same as for x <- List(1, 2); y <- List(10, 20) yield x + y?