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
A function with a signature like h
indeed cannot do many interesting things beyond performing some arithmetic on its argument. So, you have the correct intuition there.
However, it might help to look at commonly used libraries for functions with similar signatures. You'll find that the most generic ones, as you'd expect, perform generic monad operations like return
, liftM
, or join
. Also, when you use liftM
or fmap
to lift an ordinary function into a monadic function, you typically wind up with a similarly generic signature, and this is quite convenient for integrating pure functions with monadic code.
In order to use the structure that a particular monad offers, you inevitably need to use some knowledge about the specific monad you're in to build new and interesting computations in that monad. Consider the state monad, (s -> (a, s))
. Without knowing that type, we can't write get = \s -> (s, s)
, but without being able to access the state, there's not much point to being in the monad.