[Haskell-cafe] Correct usage of MonadError, ErrorT?

Daniel McAllansmith dagda at xtra.co.nz
Mon Jan 30 23:07:00 EST 2006


On Tuesday 31 January 2006 16:32, Andrew Pimlott wrote:
> On Tue, Jan 31, 2006 at 03:00:41PM +1300, Daniel wrote:
> > I've got some functions in MonadError with different Error types.  I
> > would like to map errors of one Error type onto the other Error type.
> >
> > It seems that the only facility for doing this is mapErrorT, but that
> > seems to force me to work in ErrorT rather than any old instance of
> > MonadError.
>
> What type would your mapError have?  The first idea that comes to mind
> is
>
>     mapError :: (MonadError e1 m1, MonadError e2 m2) =>
>                     (e1 -> e2) -> m1 a -> m2 a
>
> The problem here is that m1 and m2 have no relation--m1 could be IO and
> m2 (Either e2)!  Not surprisingly, we can't implement that.  

Yeah, I expected that would be difficult.
Is it actually impossible or does it just result in an explosion of code in 
the implementation, needing a clause to map each instance of MonadError to 
each other instance on MonadError?
Not that I'm suggesting that solution, it's just that I'm new to this stuff 
and don't immediately see why it's impossible (as opposed to impractical).

> So what 
> relation do you want between m1 and m2?  The only one I can think of is
> that m1 and m2 are ErrorT transforms of the same inner monad.

Yep.  That's what I was thinking of.

> In this 
> case mapErrorT fits the bill, though it would probably be more
> convenient to define your own version that maps only the error:
>
>     mapErrorTE :: (e1 -> e2) -> ErrorT e1 m a -> ErrorT e2 m a

Ok, so mapErrorT, or a convenient wrapper, is the right tool for this 
situation?

If so, doesn't using mapErrorT bind the general MonadError class to the 
specific ErrorT instance?
So,
g :: (MonadError String m, MonadIO m) => Int -> m String
would have to become
g :: (MonadIO m) => Int -> ErrorT String (m String)
and that change will propagate out through any function which calls g.

It feels bad to me to lose that generality.  Is that just a hangover from 
other/weaker languages?
Is it good advice for a new haskeller to stick to ErrorT in functions with 
errors?

>
> Do you have an example where a more generic mapError would make sense?

Where the inner monad is changed as well?  No, but I can't say that I've tried 
very hard.  I'm finding that I have to take quite small bites of haskell so 
my brain doesn't get indigestion :)

Cheers
Daniel


More information about the Haskell-Cafe mailing list