which implies that it’s the function’s responsibility to put its result into the monad. Conversely >>= gets the value from the monad, then applies the function to it. From the outside, everything stays inside the monad. ‘Get’ and ‘put’ are deliberately vague because they mean different things in each monad.

We can make a stronger statement: there are no generic monad functions to take things out of the monad. Put another way, all the function types end in m x, never just x.

Our intuitive view of >>= and return make the first two monad laws easy to understand.

The first says that the unwrapping bit of >>= exactly cancels out the wrapping done by return, leaving only the function applying bit.

The second says that you get the same cancellation if you do the unwrapping then the wrapping.

The third law tells us how to compose two monadic functions. On the left we apply first f then g to a, whilst on the right we apply the lambda expression to a. So, that lambda expression must encode applying first f then g.

Note that the monad laws are exhaustive in the sense that they cover all the non-trivial binary combinations of return and >>=:

return … >>=

>>= … return

>>= … >>=

Building on functors

Instead of building monads from scratch, we can build them from some of Haskell’s simpler abstract type classes: functor and applicative. In future Haskell might well make this the default.

We can regard all three functions as tweaking a function so that it applies to a wrapped value. However the function being transformed is different in each case:

fmap takes a pure function: (u -> v).

<*> takes a function already in the applicative: a (u -> v).

=<< takes a function which puts its result into the monad: u -> m v.

Doing it with join

Consider the implementation of fmap with >>=:

fmap f x = x >>= return . f

It’s clear that to some extent >>= duplicates the functionality in fmap, and somewhat begs the question whether we could distil the unique part of >>= into a different function. Happily we can: it’s called join, and gives us a third way to define a monad:

Note that join is almost the inverse to return, but join will only collapse two lots of wrapping into one: it won’t return a pure value from the monad. More poetically (ex The Universe of Discourse3 ):

…a monad must possess a join function that takes a ridiculous burrito of burritos and turns them into a regular burrito.

We can implement join in terms of >>=, but we need both join and fmap to implement >>=:

join x = x >>= id
x >>= f = join (fmap f x)

Finally we need different, but equivalent laws for this definition of monads:

Standard Monad Functions

Having defined the monad, one gets a whole variety of fun little functions to play with it. Many of these are listed in Control.Monad4 and you should consult that for full documentation. The notes below, are my notes on top of that.

>>

>> is a specialized version of >>=, which is defined for every monad. We omitted it above because it doesn’t add anything conceptual to the picture:

(>>) :: Monad m => m a -> m b -> m b
f >> g = f >>= const g

fail

Although it’s included in every monad, fail is a mistake, born of do-notation.