# Monads Are Not That Complicated

## An introduction for Scala developers #

If you’ve been using Scala for a while, you have been exposed to functors and monads. However, because of naming decisions in the Scala libraries, you may not be sure what these concepts refer to.

Consider these three values:

```
val opt: Option[Int] = None
val lst: List[String] = List("very nice")
val fut: Future[Double] = getValueFromElsewhere()
```

### Functor #

What do those values have in common?

- Their types have what is called a type parameter. The concept is also known as generics in many languages. If you squint a bit, you can see them as some kind of container. A
`Future`

is a container that will eventually contain a value (unless it fails). - Their types have a
`.map`

method. Using that method, you can apply a function to the values “contained” in`opt`

,`lst`

, or`fut`

. The resulting container is of the same “shape” as the container in the input. For example, the result of`lst.map(f)`

will be a`List`

of the same length as`lst`

.

Each type that has such a `.map`

method is an example of a `Functor`

. There are many more functors, but the examples above appear in everyday Scala code.

For the sake of completeness, I will add that for something to be a `Functor`

, its `.map`

method has to respect some simple laws. Those laws ensure that you don’t get surprises. One of those laws requires that `x.map(identity) == x`

for all possible values of `x`

.

These laws cannot be checked by the Scala compiler, so it’s possible to write something that looks like a `Functor`

because it has a `.map`

method, but it isn’t because it doesn’t respect the `Functor`

laws.
However, as long as you only use existing `Functor`

types and don’t write functors by yourself, you need not worry about this.

### Monad: A special case of Functor #

To apply a function `f`

using `myVal.map(f)`

, the input type of `f`

needs to be compatible with the type parameter of `myVal`

. If you check the types of the expressions involved, you will see that the code won’t compile otherwise.

However, the return type can be anything you like. **So what happens if the return type of f is itself a container of the type we’re mapping over?**

```
val g1: Int => Option[String] = ???
val myOpt: Option[Option[String]] = opt.map(g1)
val g2: String => List[Int] = ???
val myLst: List[List[Int]] = lst.map(g2)
val g3: Double => Future[Double] = ???
val myFut: Future[Future[Double]] = fut.map(g3)
```

Of course what happens is that the resulting container is nested. In some cases this may be exactly what you want, but in practice there is often an obvious way to turn the nested containers back into an unnested one.

- An optional value
`Some(Some(3))`

may for your purposes be equivalent to`Some(3)`

. Similarly, the value`Some(None)`

can be seen as equivalent to`None`

. - A nested list
`List(List(1, 2), List(3, 4))`

may be seen as equivalent to`List(1, 2, 3, 4)`

. - Two nested futures can be seen as equivalent to one (unnested)
`Future`

that completes after both the outer and the inner future have completed, and returns the result of the inner`Future`

.

Again, I’m assuming you’ve used Scala for a while, so you will know that this is exactly what `.flatten`

does.

This pattern of applying `.map`

and then `.flatten`

happens so often that there is a method for it, and unsurprisingly it is called `.flatMap`

. Roughly speaking, things that have such a `.flatMap`

method are examples of `Monad`

.

Monads are special cases of functors, so every `Monad`

is a `Functor`

, but not every `Functor`

is a `Monad`

.
Again, for something to be a `Monad`

it needs to respect some laws of behavior (in particular, it needs to respect the `Functor`

laws) but we won’t go into that here.

### Is that all there is to it? #

Yes.

The examples shown arise frequently, but there are many other types that are monads. Some of them are less intuitive, but the beauty of knowing that something is a `Monad`

is that you know it has `.flatMap`

and related methods, and due to respecting some basic laws of behavior they will do exactly what you expect.

Further reading:

- The Functor typeclass in the cats library
- The Monad typeclass in cats
- More on typeclasses in cats