I\'ve always enjoyed the following intuitive explanation of a monad\'s power relative to a functor: a monad can change shape; a functor cannot.
For example: length
The simplest type of a function satisfying the requirement I can imagine is this:
enigma :: Monad m => m () -> m ()
One can implement it in one of the following ways:
enigma1 m = m -- not changing the shape
enigma2 _ = return () -- changing the shape
This was a very simple change -- enigma2
just discards the shape and replaces it with the trivial one. Another kind of generic change is combining two shapes together:
foo :: Monad m => m () -> m () -> m ()
foo a b = a >> b
The result of foo
can have shape different from both a
and b
.
A third obvious change of shape, requiring the full power of the monad, is a
join :: Monad m => m (m a) -> m a
join x = x >>= id
The shape of join x
is usually not the same as of x
itself.
Combining those primitive changes of shape, one can derive non-trivial things like sequence
, foldM
and alike.