
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