Control.Monad.CatchIO

MonadCatchIO-mtl-0.3.0.5: Monad-transformer version of the Control.Exception module

Safe Haskell | Safe-Infered

Control.Monad.CatchIO

Synopsis

- class MonadIO m => MonadCatchIO m where
  - catch :: Exception e => m a -> (e -> m a) -> m a
  - block :: m a -> m a
  - unblock :: m a -> m a
- class (Typeable e, Show e) => Exception e where
  - toException :: e -> SomeException
  - fromException :: SomeException -> Maybe e
- throw :: (MonadIO m, Exception e) => e -> m a
- try :: (MonadCatchIO m, Exception e) => m a -> m (Either e a)
- tryJust :: (MonadCatchIO m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
- onException :: MonadCatchIO m => m a -> m b -> m a
- bracket :: MonadCatchIO m => m a -> (a -> m b) -> (a -> m c) -> m c
- bracket_ :: MonadCatchIO m => m a -> m b -> m c -> m c
- finally :: MonadCatchIO m => m a -> m b -> m a
- bracketOnError :: MonadCatchIO m => m a -> (a -> m b) -> (a -> m c) -> m c
- data Handler m a = forall e . Exception e => Handler (e -> m a)
- catches :: MonadCatchIO m => m a -> [Handler m a] -> m a

# Documentation

class MonadIO m => MonadCatchIO m where

Methods

catch :: Exception e => m a -> (e -> m a) -> m a

Generalized version of `catch`

block :: m a -> m a

Generalized version of `block`

unblock :: m a -> m a

Generalized version of `unblock`

Instances

MonadCatchIO IO |
(MonadCatchIO m, Error e) => MonadCatchIO (ErrorT e m) |
MonadCatchIO m => MonadCatchIO (ReaderT r m) |
MonadCatchIO m => MonadCatchIO (StateT s m) |
(Monoid w, MonadCatchIO m) => MonadCatchIO (WriterT w m) |
(Monoid w, MonadCatchIO m) => MonadCatchIO (RWST r w s m) |

class (Typeable e, Show e) => Exception e where

Any type that you wish to throw or catch as an exception must be an instance of the `Exception` class. The simplest case is a new exception type directly below the root:

     data MyException = ThisException | ThatException
         deriving (Show, Typeable)

     instance Exception MyException

The default method definitions in the `Exception` class do what we need in this case. You can now throw and catch `ThisException` and `ThatException` as exceptions:

    *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
    Caught ThisException

In more complicated examples, you may wish to define a whole hierarchy of exceptions:

     ---------------------------------------------------------------------
     -- Make the root exception type for all the exceptions in a compiler

     data SomeCompilerException = forall e . Exception e => SomeCompilerException e
         deriving Typeable

     instance Show SomeCompilerException where
         show (SomeCompilerException e) = show e

     instance Exception SomeCompilerException

     compilerExceptionToException :: Exception e => e -> SomeException
     compilerExceptionToException = toException . SomeCompilerException

     compilerExceptionFromException :: Exception e => SomeException -> Maybe e
     compilerExceptionFromException x = do
         SomeCompilerException a <- fromException x
         cast a

     ---------------------------------------------------------------------
     -- Make a subhierarchy for exceptions in the frontend of the compiler

     data SomeFrontendException = forall e . Exception e => SomeFrontendException e
         deriving Typeable

     instance Show SomeFrontendException where
         show (SomeFrontendException e) = show e

     instance Exception SomeFrontendException where
         toException = compilerExceptionToException
         fromException = compilerExceptionFromException

     frontendExceptionToException :: Exception e => e -> SomeException
     frontendExceptionToException = toException . SomeFrontendException

     frontendExceptionFromException :: Exception e => SomeException -> Maybe e
     frontendExceptionFromException x = do
         SomeFrontendException a <- fromException x
         cast a

     ---------------------------------------------------------------------
     -- Make an exception type for a particular frontend compiler exception

     data MismatchedParentheses = MismatchedParentheses
         deriving (Typeable, Show)

     instance Exception MismatchedParentheses where
         toException   = frontendExceptionToException
         fromException = frontendExceptionFromException

We can now catch a `MismatchedParentheses` exception as `MismatchedParentheses`, `SomeFrontendException` or `SomeCompilerException`, but not other types, e.g. `IOException`:

    *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
    Caught MismatchedParentheses
    *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
    Caught MismatchedParentheses
    *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
    Caught MismatchedParentheses
    *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: IOException))
    *** Exception: MismatchedParentheses

Methods

toException :: e -> SomeException

fromException :: SomeException -> Maybe e

Instances

Exception PatternMatchFail |
Exception RecSelError |
Exception RecConError |
Exception RecUpdError |
Exception NoMethodError |
Exception NonTermination |
Exception NestedAtomically |
Exception SomeException |
Exception ErrorCall |
Exception ArithException |

throw :: (MonadIO m, Exception e) => e -> m a

Generalized version of `throwIO`

try :: (MonadCatchIO m, Exception e) => m a -> m (Either e a)

Generalized version of `try`

tryJust :: (MonadCatchIO m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)

Generalized version of `tryJust`

onException :: MonadCatchIO m => m a -> m b -> m a

Generalized version of `onException`

bracket :: MonadCatchIO m => m a -> (a -> m b) -> (a -> m c) -> m c

Generalized version of `bracket`

bracket_

Arguments

:: MonadCatchIO m |
=> m a | computation to run first ("acquire resource")
-> m b | computation to run last ("release resource")
-> m c | computation to run in-between
-> m c |

A variant of `bracket` where the return value from the first computation is not required.

finally

Arguments

:: MonadCatchIO m |
=> m a | computation to run first
-> m b | computation to run afterward (even if an exception was raised)
-> m a |

A specialised variant of `bracket` with just a computation to run afterward.

bracketOnError

Arguments

:: MonadCatchIO m |
=> m a | computation to run first ("acquire resource")
-> (a -> m b) | computation to run last ("release resource")
-> (a -> m c) | computation to run in-between
-> m c |

Like `bracket`, but only performs the final action if there was an exception raised by the in-between computation.

data Handler m a

Generalized version of `Handler`

Constructors

forall e . Exception e => Handler (e -> m a) |

catches :: MonadCatchIO m => m a -> [Handler m a] -> m a

Generalized version of `catches`