{-# 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 :: 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 (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 :: 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 (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 :: 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