Sun, 21 Oct 2001 19:38:55 -0700, Ashley Yakeley
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