Copyright | (c) Ben Weitzman 2018 |
---|---|
License | MIT |
Maintainer | ben@costarastrolgoy.com |
Stability | experimental |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
The Catching
effect allows a way to keep track of effects that we might expect to throw
exceptions during their handling, but whose signatures don't indicate this.
As an example, consider an effect Div
that divides numbers:
data Div a where Div :: Int -> Int -> Div Int
The keen programmer is aware that this can throw an error. However, suppose that there is reason to believe that
this effect will be rarely used in a way that fails. Adding an indicator to the interface (such as by saying Div :: Int -> Int -> Div (Maybe Int)
) makes using this effect more annoying most of the time.
Nevertheless, it should be possible to handle this case when we want to. This is where Catching
can help.
Synopsis
- data Catching f e a
- catching :: forall e f a r. (Exception e, Member (Catching f e) r) => Eff '[f] a -> Eff r (Either e a)
- runCatching :: forall e r v f. (Member IO r, LastMember IO (f ': r)) => (forall a q. Member IO q => Eff (f ': q) a -> Eff q a) -> Eff (Catching f e ': (f ': r)) v -> Eff r v
- runCatching2 :: forall e r v f g. (Member IO r, Member IO (f ': r), LastMember IO (f ': (g ': r))) => (forall a q. Member g q => Eff (f ': q) a -> Eff q a) -> (forall a q. Member IO q => Eff (g ': q) a -> Eff q a) -> Eff (Catching f e ': (f ': (g ': r))) v -> Eff r v
Documentation
The Catching
effect is parameterized by the effect it is handling and the type of exceptions it will
attempt to handle (e.g. Catching Div ArithException
)
catching :: forall e f a r. (Exception e, Member (Catching f e) r) => Eff '[f] a -> Eff r (Either e a) Source #
catching
will turn an effectful computation producing an a
and using effect f
into one that produces
an Either e a
. This allows any exception that is thrown during normal handling of f
be handled explicitly.
runCatching :: forall e r v f. (Member IO r, LastMember IO (f ': r)) => (forall a q. Member IO q => Eff (f ': q) a -> Eff q a) -> Eff (Catching f e ': (f ': r)) v -> Eff r v Source #
runCatching2 :: forall e r v f g. (Member IO r, Member IO (f ': r), LastMember IO (f ': (g ': r))) => (forall a q. Member g q => Eff (f ': q) a -> Eff q a) -> (forall a q. Member IO q => Eff (g ': q) a -> Eff q a) -> Eff (Catching f e ': (f ': (g ': r))) v -> Eff r v Source #
runCatching2
can catch exceptions in effects that don't interpret directly to IO
but instead
go through an intermediary effect. In this case, three effects will be handled in one go:
- The effect
f
that is being called and is expected to be the source of an exception - The effect
g
which is not being called directly but is called instead by the handlerf
- The effect
Catching f e