[Haskell-cafe] Problem with monad transformer stack

Michael Vanier mvanier42 at gmail.com
Sun Oct 3 23:00:16 EDT 2010


  On 10/3/10 7:06 PM, Bryan O'Sullivan wrote:
> On Sun, Oct 3, 2010 at 9:40 PM, Michael Vanier <mvanier42 at gmail.com 
> <mailto:mvanier42 at gmail.com>> wrote:
>
>
>     {- This doesn't work: -}
>     newtype MyMonad a =
>      MyMonad ((StateT (MyData a) (Either SomeError) a))
>      deriving (Monad,
>                MonadState (MyData a),
>                MonadError SomeError,
>                Typeable)
>
>
> This simply isn't allowed by the generalised newtype derivation 
> machinery, because the type variable "a" appears in one of the classes 
> you're deriving.
>
> In fact, I'm not sure how you're hoping for your type to actually work 
> as a monad. If you try using (>>=) on your type synonym that currently 
> appears to typecheck, you'll find that the only value that can inhabit 
> the state parameter is bottom. Try writing out and using a definition 
> of (>>=) by hand to understand your confusion.
I disagree with your second point.  I have this in working code:

----------
newtype StateErrorIO e s a =
   StateErrorIO { runS :: (StateT s (ErrorT e IO) a) }
   deriving (Monad,
             MonadIO,
             MonadState s,
             MonadError e,
             Typeable)
----------

I can assure you that it works on non-bottom types.

As for the first point, that makes sense.  So if I do this:

----------
newtype MyMonadS s a =
   MyMonad ((StateT s (Either SomeError) a))
   deriving (Monad,
             MonadState s,
             MonadError SomeError,
             Typeable)

type MyMonad a = MyMonadS (MyData a) a
----------

it type checks.  And yeah, writing out the instances by hand is the best 
way to understand what's going on.

Mike





More information about the Haskell-Cafe mailing list