Now that Control.Monad.Error
is deprecated, and Control.Monad.Except
reigns supreme, a lot of sources online haven\'t caught up, and still show example
Short answer is: Replace Error
by nothing at all, replace ErrorT
by ExceptT
, and things should continue to work as long as you don't use Error
s methods, fail
(which now has a different definition), or failing pattern matches in do
notation.
The essential difference between the old Control.Monad.Error
system and the new Control.Monad.Except
system is that the new system imposes no class restriction on the error/exception type.
It was found that the ability to use any error/exception type at all, polymorphically, was more useful than the somewhat hacky ability to customize conversion of string error messages.
So the class Error
has simply disappeared.
As a side effect, fail
for ExceptT
now is lifted from the underlying monad. This also changes the effect of failing patterns in do
notation.
The old definition was:
fail msg = ErrorT $ return (Left (strMsg msg))
which I think is equivalent to
fail msg = throwError (strMsg msg)
If you still need this behavior, you can instead use
throwError yourIntendedErrorValue
(throwE
works instead if you're using transformers
(i.e. Control.Monad.Trans.Except
) rather than mtl
.)
The old do
pattern matching failure would apply to things like
do
Just x <- myErrorTAction
...
when the action actually returns Nothing
. This is more awkward, but you could e.g. replace it with an explicit case
match (essentially desugaring it):
do
y <- myErrorTAction
case y of
Nothing -> throwE ...
Just x -> do
...
@DanielWagner suggests the following to avoid extra indentation:
do
x <- myErrorTAction >>= maybe (throwError ...) return
...
The removal of Error
also eliminates the need for an inconsistency in naming that Control.Monad.Error
had: Most transformers follow the rule that SomethingT
is the name of the transformer, and Something
is a type alias for SomethingT ... Identity
. The old ErrorT
broke that because the Error
class was used for something entirely different.
In the new system, Except e = ExceptT e Identity
, like for other transformers.