Were you expecting to see *monads* in this book? If so, you won’t be disappointed. :)

Almost all of the data types I showed in this book are monads. This includes `Option`

, `Try`

, `Either`

, `List`

, `Seq`

, `Vector`

, `IO`

, and `ZIO`

: they’re all monads, or what we call *monadic data types*.

I won’t get into mathematical theory here, but *in Scala*, a monad is primarily a data type that properly implements `map`

and `flatMap`

methods so that it can be used in `for`

expressions. There’s a little more to it than that, but from an implementation standpoint, that’s the big thing. As I’ve shown, you can use `flatMap`

to run a few effects in sequence, and `for`

expressions to run many effects in sequence.

And as I show in Functional Programming, Simplified,

`for`

expressions are syntactic sugar that compile down to a series of`flatMap`

calls followed by a single`map`

call.

## Sequential composition

The key about monads in any language is that they allow you to guarantee that effects will occur in order (i.e., sequentially). For example, Haskell is a *lazy* (or *lazily evaluated*) programming language, and part of what that means is that whenever the Haskell compiler sees that it can run expressions in parallel, it might just do that.

However, when you prompt a user for input, like this:

`print("Your input: ")`

you *really* want to make sure that your “prompt the user” code occurs before your “read their input” code:

`val input = readInput()`

To make any sense, those operations *must* occur in that order, one after the other. In Haskell, you use its `do`

construct to ensure that expressions are run in sequence, and in Scala you similarly sequence them in `for`

expressions, like this:

```
for
_ <- promptUser()
input = readInput()
// more code here ...
```

If you recall that the `ZIO`

type is a “blueprint for describing a *concurrent* workflow,” you should think, “If `promptUser`

and `readInput`

run concurrently, I need to use a `for`

expression or `flatMap`

to make sure those two functions are called in the proper order.”

For this reason, some people refer to monads as the “semi-colon in FP.” They let us run our effects in a guaranteed sequence, so even if our functions are meant to run in parallel, `flatMap`

and `for`

expressions guarantee that they’re run in sequence, just like procedural code.

## Monads in Scala

But again, the key *in Scala* is that these monadic data types properly implement the `map`

and `flatMap`

methods inside their classes, and this is what enables them to be used in `for`

expressions. I write about this in great detail in these two resources:

- My blog post, How to Write a Scala Class That Can Be Used in a for-Expression
- My best-selling FP book, Functional Programming, Simplified

## Category Theory

For those who are interested in the theory behind names like monad, monoid, functor, and other FP terms with unusual names, the next thing you’ll want to dig into is *category theory* (which is where the name “Cats Effect” comes from).

You can find a free version of a book named *Category Theory for Programmers* at these locations:

As I’ve shown in this book, you don’t need to understand category theory to understand FP, but when you want to know where names like “map” come from, category theory is what you’re looking for.