Monads!
Every blogger that is remotely interested in functional programming seems to have to write an article that tries to explain monads at some point. So I will get this over with right with my first real post :) I will try to approach the topic with some trivial examples. The code samples are in Scala. Let’s go.
Only unary type constructors can be monads
In the course of this article, I am using three examples for monads: the List monad, the Maybe monad (aka Option aka Optional), and Future (aka Task). Based on these examples, let’s see what monads are and what monads are not.
Say, we have a value l
that is a list of strings.
In Scala:
val l: List[String]

l
is a value and values can not be monads 
List[String]
is a type and types can not be monads 
List[_]
is a type constructor and actually a monad
What does that mean?
It means that all monadrelated code is defined on the level of type constructors.
Type constructors yield a concrete type when given a type parameter.
In Scala, a type constructor with one type parameter A
may look like this:

List[A]

Option[A]

Future[A]
Only a type constructor that takes one type parameter can be a monad.
For type constructors with more parameters (such as Either[E, A]
), one of the type parameters can be chosen as the monad’s type parameter, for example by defining a type alias.
Monadic values are the result of a computation
Now that we know what a monad looks like, we can take a look at where they occur. I think the easiest way to to get an intuitive understanding of monads is to view them as the result type of a computation. In other words, a monadic value results from a function that does some computation:

a value of the type
List[A]
results from a computation that yields several values of the typeA
. For example, aList[String]
could be returned by a function that obtains all words in a given sentence. 
a value of the type
Option[A]
results from a computation that may fail or yield a value of the typeA
. For example, anOption[Int]
could be returned by a function that tries to parse an integer from a string. 
a value of the type
Future[A]
results from a computation that might take some time to yield a value of the typeA
. For example, aFuture[Boolean]
couzld be returned by a function that determines whether a given integer is a prime number.
For a monadic type M[A]
, the nature of the computation is described in M
, whereas the type of the value that the computation produces is A
.
Monadic values can be chained
OK, type constructors can represent computations and type constructors can be monads. But what makes a type constructor a monad? And why are monads useful in the context of computations? The answer to both questions are the two functions that are defined for monads. Both functions’ implementations are specific for each monad.
The first function is called pure
, point
, or return
.
It takes a value a
of the type A
and executes a default computation that yields a
:

for
List[A]
,pure(a)
produces the singleton listList(a)

for
Option[A]
,pure(a)
produces a successSome(a)

for
Future[A]
,pure(a)
produces a future that immediately finishes and yielda
The second function is called bind
or flatMap
.
It takes a value ma
of the type M[A]
and a function f
of the type A => M[B]
and applies f
to the result yielded by ma
.

for
List[A]
,flatMap(ma, f)
appliesf
to every list element inma
and returns all resulting values in a list. 
for
Option[A]
,flatMap(ma, f)
returnsNone
ifma
isNone
, and returns the result of applyingf
to the contents ofma
ifma
contains a value. 
for
Future[A]
,flatMap(ma, f)
returns a future that contains the result of applyingf
to the result ofma
.
flatMap
is the function that makes monads so useful.
It allows chaining multiple function calls that do computations to an overall function that does a combined computation.
Future
is maybe the most obvious example:
if you have functions f1: A => Future[B]
, f2: B => Future[C]
, and f3: C => Future[D]
, you can chain them easily to a new function:
def f123: A => Future[D] = (a: A) => f1(a).flatMap(f2).flatMap(f3)
That’s it for the nature of monads. I hope this post conveys an intuition of why they are useful: chaining computations. The technical details, such as Scala’s forcomprehension, the support for monads in libraries such as Cats and Scalaz, or how monads appear in other programming languages, are left for other posts.