<commit_before>---
layout: post
category: Software, functional programming, scala
title: Flatmap
---

### Background

There is a reason why `flatMap` and its cousin `map` deserves a special place in the Scala folklore. It all starts from the [combinator pattern](https://wiki.haskell.org/Combinator_pattern) popularized by the functional programming paradigm, which according to its definition, is "a style of organizing libraries centered around the idea of combining things". Usually, there are a few ways to construct some primitive values of type `T` and a few `combinators` (functions) which can combine values of type `T` to build up more complex values of type `T`. Proponents of the combinator pattern argue that it promotes modularity and composibility of the program.

Many real world libraries are built using the combinator pattern, including the Scala [collection](https://www.scala-lang.org/api/2.12.3/scala/collection/index.html) and [parser combinator](http://www.scala-lang.org/api/2.12.3/scala-parser-combinators/scala/util/parsing/combinator/Parsers.html), [Dataset](https://spark.apache.org/docs/2.1.0/api/java/org/apache/spark/sql/Dataset.html) in Spark, [Queries](http://slick.lightbend.com/doc/3.2.1/queries.html) in Slick and much more.

As someone who wants to leverage the combinator pattern, the challenge is to come up with both the type `T` and a set of combinators for `T` to encapsulate whatever computation the author wants to express. If the computation happens to be sequential by nature, that is where `Monad` comes in handy.

There might be a lot of fuzz about `Monad`, but it is not much more than a kind of `T` with a few pre defined `combinator` interfaces. At a high level, it allows us to 1) write a description of a computation and 2) have a way to apply a pure function to the result of the previous computation and transforms it into the description of the next computation. With these two weapons at our disposal, we can then write programs by taking an initial description of the computation and applying a series of these pure functions to it, representating a sequence of computations. `flatMap` is the way to apply those pure functions.

In fact, sequential compuation are so common that `Monad` becomes the basis of many types that tries to leverage the combinator pattern, to the point where many languages provide syntactic sugar to make the chaining of `flatMaps` less nested and more pleasant for eyes. In Scala, it is the keyword `for`.


### Meaning in different context

Let's look at the `flatMap` in the context of a Scala `List`.

{% highlight scala linenos=table %}

List(1, 2, 3).flatMap { i =>
  List(4, 5, 6).map { j =>
    (i, j)
  }
}

{% endhighlight %}<commit_msg>scala console<commit_after>---
layout: post
category: Software, functional programming, scala
title: Flatmap
---

### Background

There is a reason why `flatMap` and its cousin `map` deserves a special place in the Scala folklore. It all starts from the [combinator pattern](https://wiki.haskell.org/Combinator_pattern) popularized by the functional programming paradigm, which according to its definition, is "a style of organizing libraries centered around the idea of combining things". Usually, there are a few ways to construct some primitive values of type `T` and a few `combinators` (functions) which can combine values of type `T` to build up more complex values of type `T`. Proponents of the combinator pattern argue that it promotes modularity and composibility of the program.

Many real world libraries are built using the combinator pattern, including the Scala [collection](https://www.scala-lang.org/api/2.12.3/scala/collection/index.html) and [parser combinator](http://www.scala-lang.org/api/2.12.3/scala-parser-combinators/scala/util/parsing/combinator/Parsers.html), [Dataset](https://spark.apache.org/docs/2.1.0/api/java/org/apache/spark/sql/Dataset.html) in Spark, [Queries](http://slick.lightbend.com/doc/3.2.1/queries.html) in Slick and much more.

As someone who wants to leverage the combinator pattern, the challenge is to come up with both the type `T` and a set of combinators for `T` to encapsulate whatever computation the author wants to express. If the computation happens to be sequential by nature, that is where `Monad` comes in handy.

There might be a lot of fuzz about `Monad`, but it is not much more than a kind of `T` with a few pre defined `combinator` interfaces. At a high level, it allows us to 1) write a description of a computation and 2) have a way to apply a pure function to the result of the previous computation and transforms it into the description of the next computation. With these two weapons at our disposal, we can then write programs by taking an initial description of the computation and applying a series of these pure functions to it, representating a sequence of computations. `flatMap` is the way to apply those pure functions.

In fact, sequential compuation are so common that `Monad` becomes the basis of many types that tries to leverage the combinator pattern, to the point where many languages provide syntactic sugar to make the chaining of `flatMaps` less nested and more pleasant for eyes. In Scala, it is the keyword `for`.


### Meaning in different context

Let's look at `flatMap` in the context of a Scala `List`.

{% highlight scala linenos=table %}

scala> List(1, 2, 3).flatMap { i =>
     |   List(4, 5, 6).map { j =>
     |     (i, j)
     |   }
     | }
res0: List[(Int, Int)] = List((1,4), (1,5), (1,6), (2,4), (2,5), (2,6), (3,4), (3,5), (3,6))

{% endhighlight %}

{'fraction_non_alphanumeric': 0.08355698693862945, 'fraction_numerical': 0.011272141706924315, 'mean_word_length': 4.395752895752896, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 6, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1435169', 'n_tokens_mistral': 1585, 'n_tokens_neox': 1488, 'n_words': 777}