Edward Kmett\'s exceptions library does not provide a MonadMask instance for ExceptT.
Ben Gamari once asked about this and then concluded that it was explained
A class for monads which provide for the ability to account for all possible exit points from a computation, and to mask asynchronous exceptions. Continuation-based monads, and stacks such as
ErrorT e IO
which provide for multiple failure modes, are invalid instances of this class.
When you use ErrorT
/ExceptT
with IO
, having "multiple exit points" refers to the fact that you can have either a runtime exception or an exception thrown in the Monad. Either of which would end the computation.
runExceptT $ do
error "This is an exit point."
throwError "This is another exit point."
return 23
It would be possible to write a MonadMask
for ExceptT
that would be valid for all ExceptT e m a
with the precondition that the underlying monad m
is not IO. Hence the huge warning about using CatchT
with IO
(Doing so invalidates the MonadMask
instance).