MIT licensed and maintained by Nikita Volkov

Module documentation for 1.0.0.0

This version can be pinned in stack with:[email protected]:2e1042c8b036ba686e544bfdd1302fd9f66f377010fa05739e7fc000d97fa597,2430

If you have ever had to compose an exception handler for exceptions of multiple types, you know how frustraiting it can get. This library approaches this issue by providing a composable exception handler type, which has a Monoid instance.

Composability means that you can define custom partial handlers and reuse them by composing other handlers from them.

Here is an example of a composable partial handler, which only defines what to do in case of a ThreadKilled exception (the code uses the LambdaCase extension):

ignoreThreadKilled :: PartialHandler ()
ignoreThreadKilled =
  typed $ \case
    ThreadKilled -> Just $ return ()
    _ -> Nothing

Here's how you can construct a handler of type SomeException -> IO () using this library:

totalizeRethrowing $
  ignoreThreadKilled <>
  onAlreadyExists (putStrLn "Already exists")

and here is how you would do it traditionally (with the MultiWayIf extension):

\e -> if
  | Just ThreadKilled <- fromException e ->
      return ()
  | Just e' <- fromException e, isAlreadyExistsError e' ->
      putStrLn "Already exists"
  | otherwise ->
      throwIO e

Putting all the syntactic trickery to make it shorter aside, this handler is a monolith block of code. Unlike with PartialHandler you can neither decompose it into simpler ones, nor compose it with other handlers to form a more complex one.

Depends on 1 package(full list with versions):
Used by 1 package in lts-3.22(full list with versions):