Scala yield example

Like Python, scala lets you use yield to generate sequences of values. In the simplest case, these appear to be exactly the same, but if you read on, you will find that Scala’s for comprehensions have a lot more options.

For instance, take this contrived example: we generate an infinite stream (1 to infinity), loop over it, returning a new value.

var x = Stream.from(1)

val y = for (z <- x) yield z * 2

y.take(10).toList

res2: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

This does what we'd intuitively expect, similar to python or C#. It is the same as doing a "map", like so (although the map version is more terse):

var x = Stream.from(1)

val y = x.map(_ * 2)

y.take(10).toList

res2: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

The advantage of list comprehensions is that you can do a few at once, and they get run as nested loops (or rather, the nearly incomprehensible nested flatMap):

val y = 
  for(
    a <- List('a', 'b', 'c'); 
    b <- List(1,2,3)
  ) 
    yield (a, b)

y: List[(Char, Int)] = 
  List(
    (a,1), (a,2), (a,3), 
    (b,1), (b,2), (b,3), 
    (c,1), (c,2), (c,3)
  )

res6: List[Int] = List(4, 8, 12, 16, 20, 24, 28, 32, 36, 40)

You can also put "if" in:

val y = for (z <- x; if z % 2 == 0) yield z * 2

res6: List[Int] = List(4, 8, 12, 16, 20, 24, 28, 32, 36, 40)

This is equivalent to doing:

x.filter(_ % 2 == 0).map(_ * 2)