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