| Copyright | (c) Ben Weitzman 2018 |
|---|---|
| License | MIT |
| Maintainer | ben@costarastrolgoy.com |
| Stability | experimental |
| Portability | POSIX |
| Safe Haskell | None |
| Language | Haskell2010 |
Control.Monad.Freer.Catching
Description
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
fthat is being called and is expected to be the source of an exception - The effect
gwhich is not being called directly but is called instead by the handlerf - The effect
Catching f e