freer-simple-catching- Checked runtime exceptions with freer-simple

Copyright(c) Ben Weitzman 2018
Safe HaskellNone



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.



data Catching f e a Source #

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 #

Handle an effect f and a Catching f e simultaneously. In cases where catching was called, on an effect, exceptions of type e will be caught and handled. In cases where catching was not called but f was used directly, exceptions will not be caught and will bubble up.

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 handler f
  • The effect Catching f e