It’s useful to step back from details for a few moments and look at the weaknesses and strengths of programming with monads and monad transformers.
Probably the biggest practical irritation of working with monads is that a
monad’s type constructor often gets in our way when we’d like to use
pure code. Many useful pure functions need monadic counterparts,
simply to tack on a placeholder parameter
some monadic type constructor:
:t filterfilter :: (a -> Bool) -> [a] -> [a]
:i filterMfilterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] -- Defined in Control.Monad
However, the coverage is incomplete: the standard libraries don’t always provide monadic versions of pure functions.
The reason for this lies in history.
Eugenio Moggi introduced the idea of using monads for programming in 1988,
around the time the Haskell 1.0 standard was being developed. Many of
the functions in today’s
Prelude date back to Haskell
1.0, which was released in 1990. In 1991, Philip Wadler started
writing for a wider functional programming audience about the
potential of monads, at which point, they began to be put in
Not until 1996 and the release of
Haskell 1.3 did the standard acquire support for monads. By this time,
the language designers were already constrained by backwards
compatibility: they couldn’t change the signatures of functions in the
Prelude, because it would have broken existing