for comprehension

Scala for/yield examples (for-loop and yield examples)

I just found some notes from when I first began working with Scala, and I was working with the yield keyword in for loops. If you haven't worked with something like yield before, it will be helpful to know how it works. Here's a statement of how the yield keyword works in for loops, based on the documentation in the book, Programming in Scala:

Scala: Examples of for-expressions being converted to map and flatMap

Without any explanation, here are a couple of source code examples from my book, Learning Functional Programming in Scala. The only thing I’ll say about this code is that I created it in the process of writing that book, and the examples show how the Scala compiler translates for-expressions into map and flatMap calls behind the scenes.

How to use multiple Futures in a Scala for-comprehension

If you want to create multiple Scala Futures and merge their results together to get a result in a for comprehension, the correct approach is to (a) first create the futures, (b) merge their results in a for comprehension, then (c) extract the result using onComplete or a similar technique.

This is a page from my book, Functional Programming, Simplified

How to Enable the Use of Multiple Generators in a ‘for’ Expression

One cool thing about for expressions is that you can use multiple generators inside of them. This lets you do some nice analytics when you have some interesting data relationships.

For instance, suppose you have some data like this:

This is a page from my book, Functional Programming, Simplified

How to Enable Filtering in a Scala `for` Expression

Next, let’s see if we can use a filtering clause inside of a for expression with the Sequence code we have so far.

Trying to use a filtering expression

When I paste the current Sequence class and this code into the Scala REPL:

val ints = Sequence(1,2,3,4,5)

val res = for {
    i <- ints
    if i > 2
} yield i*2

I see the following error message:

This is a page from my book, Functional Programming, Simplified

How To Make Sequence Work as a Single Generator in a `for` Expression

Getting Sequence to work as a generator in a simple for loop was cool, but does adding foreach let Sequence also work when I add yield? Let’s see.

When I paste this code into the REPL:

val ints = Sequence(1,2,3)

for {
    i <- ints
} yield i*2

I see this error message:

This is a page from my book, Functional Programming, Simplified

How to Make Sequence Work in a Simple ‘for’ Loop

So far I have this Sequence class:

case class Sequence[A](initialElems: A*) {

    private val elems = scala.collection.mutable.ArrayBuffer[A]()

    // initialize
    elems ++= initialElems

}

With that code I can create new Sequence instances like this:

val strings = Sequence("a", "b", "c")
val nums = Sequence(1, 2, 3, 4, 5)

Next, I’ll modify Sequence so I can use it as a generator in a for loop.

This is a page from my book, Functional Programming, Simplified

How to Create a Sequence Class to be Used in a ‘for’ Expression

The best way I know to demonstrate how the Scala for expression works is for us to build our own collection class.

To keep things simple I’m going to create a custom class as a “wrapper” around an existing Scala collection class. The reason for this is that I want you to focus on the effects that writing map, flatMap, withFilter, and foreach methods have on how the class works in a for expression — not on writing the gory internals of a collection class.