[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