XII. Monads

So far I have left out one of functions a monad is required to have and avoided explaining two of the three axioms that any implementation should satisfy.

The missing function is

fail :: Monad m => String -> m a

This function exists independent of the axioms and is for error handling. Haskell has other ways of handling errors and the fail function seems to be used very little.

The two additional axioms ensure that return acts something like an algebraic identity with respect to the (>>=) combinator. Recall that for addition the identity is 0, for multiplication it is 1, and for composition of functions the identity is

id :: a -> a
id x = x

The pattern looks the same for all three of these examples.

x + 0 == 0 + x == x
x * 1 == 1 * x == x
f.id == id.f == f

For monads the pattern is a bit more complex because unlike normal algebraic operators (>>=) does not take the same kind of thing on the left and the right. On the left a monadic object is needed and on the right a monad making function is needed. Even so the right identity axiom looks pretty normal:

mon >>= return == mon

To get return on the left of the >>= combinator we must make it into a monadic object by applying it to some object x. The left identity axiom looks like this

return x >>= f == f x

which pretty much says that any f will behave the same if its argument is passed through return as it will if its argument is used directly. This is not the usual kind of equality we see for identity axioms but the meaning is effectively the same.

Together with the associative axiom of Section V, the right and left identity axioms make up the rules every implementation of a monad must follow.