Add Error capability
aherrmann opened this issue · 1 comments
As requested in #17 (comment) .
Some points for discussion:
- Is a tag meaningful and useful?
It could be used to select a layer in a transformer stack. E.g.example :: ExampleM () example = do let catchIO = catch @"io" throw @"either" MyException `catchIO` \MyExcetion -> pure () newtype ExampleM a = ExampleM (ExceptT MyException IO)
- Should we follow
Control.Monad.Catch
and have separate capabilities for throw/catch/mask, or rather one class for all?
Separate classes seem more flexible. E.g. throw works in cases where mask doesn't. - Should the error type be an index to
HasError
?
IfHasError
should cover e.g.ExceptT
then, it seems, the answer should be yes.
The generalIO
case could be covered with a synonymHasError_
wheree ~ SomeException.
cc @aspiwack
Is a tag meaningful and useful?
Yes, because just as state and reader compose with lenses, exceptions compose with prisms.
So that if you have a bunch of your program which can throw (and presumably catch
) PuddingException
-s and another bit throws PoundCakeException
-s, then you can implement that as one
Either CakeException
data CakeException = Pudding PuddingException | PoundCake PoundCakeException
I'm not sure how to best do the interaction with IO
, however. Maybe by making a special type of exception TaggedException tag e
which is a newtype for e
?
Should we follow Control.Monad.Catch and have separate capabilities for throw/catch/mask, or rather one class for all?
I have no opinion on this one.
Should the error type be an index to HasError
Yes.
The general IO case could be covered with a synonym HasError_ where e ~ SomeException.
Well, you can also implement HasError tag AnotherExceptionType
with IO
.