# For-comprehension, a Scala language concept

Last updated

The for-comprehension is highly important syntatic enhancement in functional programming languages.

``````assert(List(1, 2, 3).map(num => num + 1) == List(2, 3, 4))
``````

Becomes:

``````assert((for (num <- List(1, 2, 3)) yield num + 1) == List(2, 3, 4))
``````

And

``````val Multiplier = 10

assert(
List(1, 2, 3)
.flatMap(num =>
List(num * Multiplier - 1, num * Multiplier, num * Multiplier + 1)
)
.map(num => num + 1) == List(10, 11, 12, 20, 21, 22, 30, 31, 32)
)
``````

Becomes:

``````val Multiplier = 10

val result: List[Int] = for {
num <- List(1, 2, 3)
anotherNum <-
List(num * Multiplier - 1, num * Multiplier, num * Multiplier + 1)
} yield anotherNum + 1

assert(result == List(10, 11, 12, 20, 21, 22, 30, 31, 32))
``````

Even more interestingly, an 'if' guard may be available for some container types, such as:

``````val Multiplier = 10

object Odd {
def unapply(num: Int): Option[Int] = Option.when(num % 2 == 1)(num)
}

val result: List[Int] = for {
Odd(num) <- List(1, 2, 3) if num > 2
anotherNum <-
List(num * Multiplier - 1, num * Multiplier, num * Multiplier + 1)
} yield anotherNum + 1

assert(result == List(30, 31, 32))
``````

Interestingly, this applies to pattern matching as well, which you can do inside for-comprehensions!

## Background

Prior to Scala and F#, for-comprehensions were widely used in Haskell and XQuery. The key selling point is how much more concise they can make the code. There are numerous definitions of what they do (such as being 'a way to compose Monads'), However the most-straightforward way to see them is as something that lets you combine sequences of .map and .flatMap, as well as .collect/.withFilter in a very straight-forward way.

This can include the IO type of cats-effect, as well as simple types like Option Type and other container types like Lazy List or View.

What is cool in Scala is that often Option types can be combined with Iterables, allowing for very terse syntax.

for-comprehensions are in particular useful where code becomes unreadable due to a large number of chains of .map and .flatMap - and you just want to have everything in one column. This anti-pattern of unreadable chains of code is also known as callback hell (example).

Various names are given for for-comprehensions in different languages: do-notation in Haskell, await-async in JavaScript, list comprehensions in F#, generators in Python. Even SQL queries can be considered a form of for-comprehensions.

# Scala Algorithms: The most comprehensive library of algorithms in standard pure-functional Scala

### Study our 89 Scala Algorithms: 6 fully free, 89 published & 0 upcoming

Fully unit-tested, with explanations and relevant concepts; new algorithms published about once a week.

### Explore the 21 most useful Scala concepts

To save you going through various tutorials, we cherry-picked the most useful Scala concepts in a consistent form.

## Register now (free)

Register with GitHub

This gives you access to free test cases & hints for all our 89 published algorithms as well as our installation-free Scala IDE.

You can then choose to subscribe to "Scala Algorithms Unlimited", which gets you access to every current and upcoming algorithm solution. We use Stripe so your data is safe.

We will e-mail you at most once per week with new algorithms and relevant content.
Your data is protected and unsubscribing is straightforward. 