[Haskell-beginners] Effective use of nested Monads

Brent Yorgey byorgey at seas.upenn.edu
Mon Feb 11 06:17:46 CET 2013


On Sun, Feb 10, 2013 at 02:53:18PM -0800, David Hinkes wrote:
> Hi haskell-beginners,
> 
> I'm starting to come to the idea of exposing a Monad as a means of
> controlling an API.  So, I've started creating my own Monad data types
> based on classical monads.  However, I'm running into a problem regarding
> creating monad definitions when using nested Monads.
> 
> For example:
> 
> newtype Example m o = Example {
>   runExample :: State Int (m o)
> }
> 
> Is there a clean way to make Example a monad?

Actually, there isn't!  This is one way in which monads turn out to be
*too* powerful: they don't compose very well.  If m and n are monads,
then their composition (that is, a type like newtype Composed a =
Composed (m (n a))) is *not* necessarily a monad!  So "nesting" monads
in this way is usually not a good idea.

What you want are called "monad transformers", which give you a way to
"compose" certain monads (though it's more complicated than just
nesting them).  You can do your Example type something like this:

  newtype Example m o = Example {
    runExample :: StateT Int m o
  }

where StateT is the State monad transformer, defined in the
'transformers' package (and also exported from the 'mtl' package).  I
refer you to the typeclassopedia for more information and links to
further reading:

  http://www.haskell.org/haskellwiki/Typeclassopedia#Monad_transformers

-Brent



More information about the Beginners mailing list