
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? instance Monad m => Monad (Example m) where -- return is easy return = Example . return . return -- bind is hard. -- f :: o -> Example m p -- a :: Example m o a >>= f = ... My intuition tells me that this should be simple, I should just use the State's bind operation, but I can't seem to make it work. Any advise would be great. Thanks, Dave -- David Hinkes


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

On Sun, Feb 10, 2013 at 9:17 PM, Brent Yorgey
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 Thanks Brent, I'll try to re-organize around the transforms.
participants (3)
-
Brent Yorgey
-
David Hinkes
-
Ozgur Akgun