5.02 MonadError Broke My Code

Marcin 'Qrczak' Kowalczyk qrczak@knm.org.pl
Wed, 24 Oct 2001 13:50:20 +0000 (UTC)


Sun, 21 Oct 2001 19:38:55 -0700, Ashley Yakeley <ashley@semantic.org> pisze:

> MonadError seems to have been redefined in 5.02 to have a fundep:
> 
> 5.00.2:
> 
>     class (Monad m) => MonadError e m
> 
> 5.02:
> 
>     class (Monad m) => MonadError e m | m -> e
> 
> Why?

It allows some practical functions which would be awkward to write
without the fundep. For example:

data ParseError = ...
class HasParseError e where
    inject :: ParseError -> e

parseInteger :: (MonadError m e, HasParseError e) => m Integer
-- This type is ambiguous without the fundep because the main part of
-- the type doesn't mention e.

You could argue that we should write this instead:

parseString :: MonadError m ParseError => String -> m ()

but this style isn't always feasible.

It would force to have a concrete error type in all places where the
error type is not directly visible in the type of the whole function.
I don't want to commit to a particular error type in generic parsing
library for example - the library only specifies properties of the
error type using classes and gives several choices for it; details
of the error type are specific to places where the library is used.

Also a constraint like 'MonadError m ParseError' which mentions
a concrete type can't be put in an instance context without
-fallow-undecidable-instances. I have an example where putting this
in an instance context is useful: there is a large set of constraints
(six) which is used in many functions, so they are packed in a subclass
with no methods which serves as a "class synonym".

> Anyway, because of GHC's naive instance overlapping checking, it broke my 
> code:
> 
>     instance (JVMMonad m) => MonadError ThrowableRef m where

Sorry about that. A single MonadError class can't simultaneously
allow both ways of associating error types with monads.

I guess you can move 'MonadError ThrowableRef m' to superclasses of
JVMMonad and make MonadError instances for all types in this class
separately.

-- 
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZASTĘPCZA
QRCZAK