    {-# LANGUAGE ScopedTypeVariables #-}

    -- | Utilities for working with new Control.Exception
    module Control.Exc (ignoringException, printingException, orException)
    where

    import Prelude
    import Control.Exception (catch, SomeException)

    -- | Execute IO (Maybe a) action replacing all exceptions with return value of Nothing.
    ignoringException :: IO (Maybe a) -> IO (Maybe a)
    ignoringException :: forall a. IO (Maybe a) -> IO (Maybe a)
    ignoringException IO (Maybe a)
    f = IO (Maybe a)
    f IO (Maybe a) -> (SomeException -> IO (Maybe a)) -> IO (Maybe a)
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    `catch` SomeException -> IO (Maybe a)
    forall {m :: * -> *} {a}. Monad m => SomeException -> m (Maybe a)
    ignore
      where ignore :: SomeException -> m (Maybe a)
    ignore (SomeException
    _ :: SomeException) = Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe a
    forall a. Maybe a
    Nothing

    -- | Execute IO () action, replacing all exceptions with messages
    printingException :: String -> IO a -> IO a
    printingException :: forall a. String -> IO a -> IO a
    printingException String
    desc IO a
    f = IO a
    f IO a -> (SomeException -> IO a) -> IO a
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    `catch` SomeException -> IO a
    forall {m :: * -> *} {a}. MonadFail m => SomeException -> m a
    handler
      where handler :: SomeException -> m a
    handler (SomeException
    err :: SomeException) = String -> m a
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> m a) -> String -> m a
    forall a b. (a -> b) -> a -> b
    $ [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [String
    desc, String
    " failed: ", SomeException -> String
    forall a. Show a => a -> String
    show SomeException
    err]

    -- | Execute IO () action, replacing all exceptions with messages
    orException :: IO a -> IO a -> IO a
    orException :: forall a. IO a -> IO a -> IO a
    orException IO a
    f IO a
    g = IO a
    f IO a -> (SomeException -> IO a) -> IO a
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    `catch` SomeException -> IO a
    handler
      where handler :: SomeException -> IO a
    handler (SomeException
    _ :: SomeException) = IO a
    g