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
.