by Tom Ellis on 2nd September 2012
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]
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.
Monad, really?A Monad is really a Category k with an identification between k a b and a -> k () b.