Jaguarpaw Blog - What is a Monad, really?

by Tom Ellis on 2nd September 2012

What is a Monad, really?

(A tutorial for experts)

Monad is a typeclass with methods return and (>>=)

class Monad m where
    (>>=) :: m a -> (a -> m b) -> m b
    return :: a -> m a

which satisfy

return a >>= f = f a
m >>= return = m
(m >>= f) >>= g = m >>= (\x -> f x >>= g)

These conditions are obscure. There’s a more transparent way of expressing them. First we introduce a new operator in terms of >>=

(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
g <=< f = \x -> f x >>= g

Observe that >>= can also be written in terms of <=<

m >>= g = const m () >>= g = (\() -> const m () >>= g) () = (g <=< const m) ()

and note that

g <=< return = \x -> return x >>= g = \x -> return x >>= g = \x -> g x = g

return <=< g = \x -> g x >>= return = \x -> g x = g

(h <=< g) <=< f = \x -> f x >>= (h <=< g) = \x -> f x >>= (\y -> g y >>= h)
                = \x -> (f x >>= g) >>= h = h <=< (\x -> f x >>= g)
                = h <=< (g <=< f)

in brief

g <=< return = g
return <=< g = g
(h <=< g) <=< f = h <=< (g <=< f)

This is exactly what is required for a -> m b to be a Category instance. (Not quite a -> m b but a newtype wrapper around it!) It is called the Kleisli category of m.

[See also Monad Laws at the Haskell Wiki]

But what is a Monad, really?

So a Monad m gives rise to Category k such that m is isomorphic to k (). What does the Monad have over and above this Category? In other words, suppose I have a Category instance K. What conditions does it need to satisfy for K () to be a Monad? The answer is “not much”: it simply requires an identification between K a b and a -> K () b, i.e. two functions

raise :: K a b -> a -> K () b
lower :: (a -> K () b) -> K a b

satisfying

raise . lower = lower . raise = id

for then I can declare

instance Monad (K ()) where
    return = raise id
    m >>= f = (f <=< const m) ()
        where
        (<=<) :: (b -> K () c) -> (a -> K () b) -> (a -> K () c)
        f <=< g = raise (lower f <<< lower g)

Taking the Kleisli category of K () gives us a Category instance isomorphic to K. If K is the Kleisli category of m then this monad instance for K () is isomorphic to m.

So what is a Monad, really?

A Monad is really a Category k with an identification between k a b and a -> k () b.

Contact the author