On 10/3/10 7:06 PM, Bryan O'Sullivan wrote:
On Sun, Oct 3, 2010 at 9:40 PM, Michael Vanier <mvanie...@gmail.com <mailto:mvanie...@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



_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to