-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Explicitly typed, checked exceptions with stack traces
--   
--   This package provides explicitly typed, checked exceptions as a
--   library.
--   
--   Computations throwing different types of exception can be combined
--   seamlessly.
--   
--   <i>Example</i>
--   
--   <pre>
--   data Expr = Add Expr Expr | Div Expr Expr | Val Double
--   eval (Val x)     = return x
--   eval (Add a1 a2) = do
--      v1 &lt;- eval a1
--      v2 &lt;- eval a2
--      let sum = v1 + v2
--      if sum &lt; v1 || sum &lt; v2 then throw SumOverflow else return sum
--   eval (Div a1 a2) = do
--      v1 &lt;- eval a1
--      v2 &lt;- eval a2
--      if v2 == 0 then throw DivideByZero else return (v1 / v2)
--   </pre>
--   
--   <pre>
--   data DivideByZero = DivideByZero deriving (Show, Typeable)
--   data SumOverflow  = SumOverflow  deriving (Show, Typeable)
--   </pre>
--   
--   <pre>
--   instance Exception DivideByZero
--   instance Exception SumOverflow
--   </pre>
--   
--   GHCi infers the following types
--   
--   <pre>
--   eval :: (Throws DivideByZero l, Throws SumOverflow l) =&gt; Expr -&gt; EM l Double
--   eval `catch` \ (e::DivideByZero) -&gt; return (-1)  :: Throws SumOverflow l =&gt; Expr -&gt; EM l Double
--   runEM(eval `catch` \ (e::SomeException) -&gt; return (-1))  :: Expr -&gt; Double
--   </pre>
--   
--   In addition to explicitly typed exceptions this package provides:
--   
--   <ul>
--   <li>Support for explicitly documented, unchecked exceptions (via
--   <a>Control.Monad.Exception.tryEMT</a>).</li>
--   <li>Support for selective unchecked exceptions (via
--   <a>Control.Monad.Exception.UncaughtException</a>).</li>
--   <li>Support for exception call traces via
--   <a>Control.Monad.Loc.MonadLoc</a>. <i>Example:</i></li>
--   </ul>
--   
--   <pre>
--   f () = do throw MyException
--   g a  = do f a
--   
--   main = runEMT $ do g () `catchWithSrcLoc`
--                          \loc (e::MyException) -&gt; lift(putStrLn$ showExceptionWithTrace loc e)
--   
--   -- Running main produces the output:
--   
--   *Main&gt; main
--    MyException
--      in f, Main(example.hs): (1,6)
--         g, Main(example.hs): (2,6)
--         main, Main(example.hs): (5,9)
--         main, Main(example.hs): (4,16)
--   </pre>
@package control-monad-exception
@version 0.11.4


-- | Defines the <tt>Throws</tt> binary relationship between types.
module Control.Monad.Exception.Throws

-- | <tt>Throws</tt> is a type level binary relationship used to model a
--   list of exceptions.
--   
--   There is only one case in which the user must add further instances to
--   <tt>Throws</tt>. If your sets of exceptions are hierarchical then you
--   need to teach <a>Throws</a> about the hierarchy.
--   
--   <ul>
--   <li><i><i>Subtyping</i></i> As there is no way to automatically infer
--   the subcases of an exception, they have to be encoded manually
--   mirroring the hierarchy defined in the defined <a>Exception</a>
--   instances. For example, the following instance encodes that
--   <tt>MyFileNotFoundException</tt> is a subexception of
--   <tt>MyIOException</tt> :</li>
--   </ul>
--   
--   <pre>
--   instance Throws MyFileNotFoundException (Caught MyIOException l)
--   </pre>
--   
--   <a>Throws</a> is not a transitive relation and every ancestor relation
--   must be explicitly encoded.
--   
--   <pre>
--                                                            --   TopException
--                                                            --         |
--   instance Throws MidException   (Caught TopException l)   --         |
--                                                            --   MidException
--   instance Throws ChildException (Caught MidException l)   --         |
--   instance Throws ChildException (Caught TopException l)   --         |
--                                                            --  ChildException
--   </pre>
--   
--   Note that <a>SomeException</a> is automatically an ancestor of every
--   other exception type.
class Exception e => Throws e l

-- | A type level witness of a exception handler.
data Caught e l

-- | <tt>CheckedException</tt> adds a phantom type parameter <tt>l</tt> to
--   <tt>SomeException</tt>
newtype CheckedException l
CheckedException :: SomeException -> CheckedException l
[checkedException] :: CheckedException l -> SomeException
instance GHC.Show.Show (Control.Monad.Exception.Throws.CheckedException l)
instance Control.Monad.Exception.Throws.Throws e l => Control.Monad.Exception.Throws.Throws e (Control.Monad.Exception.Throws.Caught e' l)
instance GHC.Exception.Type.Exception e => Control.Monad.Exception.Throws.Throws e (Control.Monad.Exception.Throws.Caught e l)
instance GHC.Exception.Type.Exception e => Control.Monad.Exception.Throws.Throws e (Control.Monad.Exception.Throws.Caught GHC.Exception.Type.SomeException l)
instance Control.Monad.Exception.Throws.Throws GHC.Exception.Type.SomeException (Control.Monad.Exception.Throws.Caught GHC.Exception.Type.SomeException l)


-- | Defines the (not so useful anymore) <a>MonadCatch</a> type class.
module Control.Monad.Exception.Catch
class (Monad m, Monad m') => MonadCatch e m m' | e m -> m', e m' -> m
catch :: MonadCatch e m m' => m a -> (e -> m' a) -> m' a
catchWithSrcLoc :: MonadCatch e m m' => m a -> ([String] -> e -> m' a) -> m' a

-- | Any type that you wish to throw or catch as an exception must be an
--   instance of the <tt>Exception</tt> class. The simplest case is a new
--   exception type directly below the root:
--   
--   <pre>
--   data MyException = ThisException | ThatException
--       deriving Show
--   
--   instance Exception MyException
--   </pre>
--   
--   The default method definitions in the <tt>Exception</tt> class do what
--   we need in this case. You can now throw and catch
--   <tt>ThisException</tt> and <tt>ThatException</tt> as exceptions:
--   
--   <pre>
--   *Main&gt; throw ThisException `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   </pre>
--   
--   In more complicated examples, you may wish to define a whole hierarchy
--   of exceptions:
--   
--   <pre>
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e =&gt; SomeCompilerException e
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e =&gt; SomeFrontendException e
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving Show
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   </pre>
--   
--   We can now catch a <tt>MismatchedParentheses</tt> exception as
--   <tt>MismatchedParentheses</tt>, <tt>SomeFrontendException</tt> or
--   <tt>SomeCompilerException</tt>, but not other types, e.g.
--   <tt>IOException</tt>:
--   
--   <pre>
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   </pre>
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e

-- | Render this exception value in a human-friendly manner.
--   
--   Default implementation: <tt><a>show</a></tt>.
displayException :: Exception e => e -> String

-- | The <tt>SomeException</tt> type is the root of the exception type
--   hierarchy. When an exception of type <tt>e</tt> is thrown, behind the
--   scenes it is encapsulated in a <tt>SomeException</tt>.
data SomeException
SomeException :: e -> SomeException
instance GHC.Exception.Type.Exception e => Control.Monad.Exception.Catch.MonadCatch e GHC.Types.IO GHC.Types.IO

module Control.Monad.Exception.Base
type CallTrace = [String]

-- | A Monad Transformer for explicitly typed checked exceptions.
newtype EMT l m a
EMT :: m (Either (CallTrace, CheckedException l) a) -> EMT l m a
[unEMT] :: EMT l m a -> m (Either (CallTrace, CheckedException l) a)

-- | Run a computation explicitly handling exceptions
tryEMT :: Monad m => EMT AnyException m a -> m (Either SomeException a)
tryEMTWithLoc :: Monad m => EMT AnyException m a -> m (Either (CallTrace, SomeException) a)
runEMTGen :: forall l m a. Monad m => EMT l m a -> m a
data AnyException
data NoExceptions
data ParanoidMode

-- | Run a safe computation
runEMT :: Monad m => EMT NoExceptions m a -> m a

-- | Run a safe computation checking even unchecked
--   (<a>UncaughtException</a>) exceptions
runEMTParanoid :: Monad m => EMT ParanoidMode m a -> m a

-- | The throw primitive
throw :: (Exception e, Throws e l, Monad m) => e -> EMT l m a

-- | Rethrow an exception keeping the call trace
rethrow :: (Throws e l, Monad m) => CallTrace -> e -> EMT l m a
showExceptionWithTrace :: Exception e => [String] -> e -> String

-- | UncaughtException models unchecked exceptions
--   
--   In order to declare an unchecked exception <tt>E</tt>, all that is
--   needed is to make <tt>e</tt> an instance of <a>UncaughtException</a>
--   
--   <pre>
--   instance UncaughtException E
--   </pre>
--   
--   Note that declaring an exception E as unchecked does not automatically
--   turn its children unchecked too. This is a shortcoming of the current
--   encoding.
class Exception e => UncaughtException e

-- | A monad of explicitly typed, checked exceptions
type EM l = EMT l Identity

-- | Run a computation explicitly handling exceptions
tryEM :: EM AnyException a -> Either SomeException a
tryEMWithLoc :: EM AnyException a -> Either (CallTrace, SomeException) a

-- | Run a safe computation
runEM :: EM NoExceptions a -> a

-- | Run a computation checking even unchecked
--   (<tt>UncaughtExceptions</tt>) exceptions
runEMParanoid :: EM ParanoidMode a -> a

-- | <tt>FailException</tt> is thrown by Monad <a>fail</a>
data FailException
FailException :: String -> FailException

-- | <tt>MonadZeroException</tt> is thrown by MonadPlus <a>mzero</a>
data MonadZeroException
MonadZeroException :: MonadZeroException

-- | This function may be used as a value for <a>mplus</a> in
--   <a>MonadPlus</a>
mplusDefault :: Monad m => EMT l m a -> EMT l m a -> EMT l m a
mapLeft :: (a -> b) -> Either a r -> Either b r
instance GHC.Show.Show Control.Monad.Exception.Base.FailException
instance GHC.Show.Show Control.Monad.Exception.Base.MonadZeroException
instance Control.Monad.Exception.Throws.Throws Control.Monad.Exception.Base.MonadZeroException l => GHC.Base.MonadPlus (Control.Monad.Exception.Base.EM l)
instance Control.Monad.Exception.Throws.Throws Control.Monad.Exception.Base.MonadZeroException l => GHC.Base.Alternative (Control.Monad.Exception.Base.EM l)
instance GHC.Exception.Type.Exception Control.Monad.Exception.Base.MonadZeroException
instance GHC.Base.Monad m => Control.Monad.Fail.MonadFail (Control.Monad.Exception.Base.EMT l m)
instance GHC.Exception.Type.Exception Control.Monad.Exception.Base.FailException
instance Control.Monad.Exception.Base.UncaughtException e => Control.Monad.Exception.Throws.Throws e Control.Monad.Exception.Base.NoExceptions
instance Control.Monad.Exception.Base.UncaughtException GHC.Exception.Type.SomeException
instance GHC.Exception.Type.Exception e => Control.Monad.Exception.Throws.Throws e Control.Monad.Exception.Base.AnyException
instance GHC.Base.Monad m => GHC.Base.Functor (Control.Monad.Exception.Base.EMT l m)
instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Exception.Base.EMT l m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.Exception.Base.EMT l m)
instance (GHC.Exception.Type.Exception e, Control.Monad.Exception.Throws.Throws e l, GHC.Base.Monad m) => Control.Failure.Failure e (Control.Monad.Exception.Base.EMT l m)
instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.Exception.Base.EMT l)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Control.Monad.Exception.Base.EMT l m)
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Control.Monad.Exception.Base.EMT l m)
instance Control.Monad.Trans.Control.MonadTransControl (Control.Monad.Exception.Base.EMT l)
instance GHC.Base.Monad m => Control.Monad.Loc.MonadLoc (Control.Monad.Exception.Base.EMT l m)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.Exception.Base.EMT l m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.Exception.Base.EMT l m)


-- | A Monad Transformer for explicitly typed checked exceptions, described
--   in detail by:
--   
--   <ul>
--   <li>Jose Iborra, "Explicitly Typed Exceptions for Haskell", PADL'10,
--   January 2010,
--   <a>http://dl.dropbox.com/s/lgm12trtl0swtra/PADL10.pdf?dl=1</a></li>
--   </ul>
--   
--   The exceptions thrown by a computation are inferred by the typechecker
--   and appear in the type signature of the computation as <a>Throws</a>
--   constraints.
--   
--   Exceptions are defined using the extensible exceptions framework of
--   Marlow (documented in <a>Control.Exception</a>):
--   
--   <ul>
--   <li><i>An Extensible Dynamically-Typed Hierarchy of Exceptions</i>, by
--   Simon Marlow, in <i>Haskell '06</i>.</li>
--   </ul>
--   
--   <i>Example</i>
--   
--   <pre>
--   data DivideByZero = DivideByZero deriving (Show, Typeable)
--   data SumOverflow  = SumOverflow  deriving (Show, Typeable)
--   </pre>
--   
--   <pre>
--   instance Exception DivideByZero
--   instance Exception SumOverflow
--   </pre>
--   
--   <pre>
--   data Expr = Add Expr Expr | Div Expr Expr | Val Double
--   </pre>
--   
--   <pre>
--   eval (Val x)     = return x
--   eval (Add a1 a2) = do
--      v1 &lt;- eval a1
--      v2 &lt;- eval a2
--      let sum = v1 + v2
--      if sum &lt; v1 || sum &lt; v2 then throw SumOverflow else return sum
--   eval (Div a1 a2) = do
--      v1 &lt;- eval a1
--      v2 &lt;- eval a2
--      if v2 == 0 then throw DivideByZero else return (v1 / v2)
--   </pre>
--   
--   GHCi infers the following types
--   
--   <pre>
--   eval                                             :: (Throws DivideByZero l, Throws SumOverflow l) =&gt; Expr -&gt; EM l Double
--   eval `catch` \ (e::DivideByZero) -&gt; return (-1)  :: Throws SumOverflow l =&gt; Expr -&gt; EM l Double
--   runEM(eval `catch` \ (e::SomeException) -&gt; return (-1))
--                                                    :: Expr -&gt; Double
--   </pre>
module Control.Monad.Exception.Pure

-- | A monad of explicitly typed, checked exceptions
type EM l = EMT l Identity

-- | Run a computation explicitly handling exceptions
tryEM :: EM AnyException a -> Either SomeException a
tryEMWithLoc :: EM AnyException a -> Either (CallTrace, SomeException) a

-- | Run a safe computation
runEM :: EM NoExceptions a -> a

-- | Run a computation checking even unchecked
--   (<tt>UncaughtExceptions</tt>) exceptions
runEMParanoid :: EM ParanoidMode a -> a

-- | A Monad Transformer for explicitly typed checked exceptions.
newtype EMT l m a
EMT :: m (Either (CallTrace, CheckedException l) a) -> EMT l m a
[unEMT] :: EMT l m a -> m (Either (CallTrace, CheckedException l) a)
type CallTrace = [String]

-- | Run a computation explicitly handling exceptions
tryEMT :: Monad m => EMT AnyException m a -> m (Either SomeException a)
tryEMTWithLoc :: Monad m => EMT AnyException m a -> m (Either (CallTrace, SomeException) a)

-- | Run a safe computation
runEMT :: Monad m => EMT NoExceptions m a -> m a

-- | Run a safe computation checking even unchecked
--   (<a>UncaughtException</a>) exceptions
runEMTParanoid :: Monad m => EMT ParanoidMode m a -> m a
data AnyException

-- | UncaughtException models unchecked exceptions
--   
--   In order to declare an unchecked exception <tt>E</tt>, all that is
--   needed is to make <tt>e</tt> an instance of <a>UncaughtException</a>
--   
--   <pre>
--   instance UncaughtException E
--   </pre>
--   
--   Note that declaring an exception E as unchecked does not automatically
--   turn its children unchecked too. This is a shortcoming of the current
--   encoding.
class Exception e => UncaughtException e

-- | <tt>Throws</tt> is a type level binary relationship used to model a
--   list of exceptions.
--   
--   There is only one case in which the user must add further instances to
--   <tt>Throws</tt>. If your sets of exceptions are hierarchical then you
--   need to teach <a>Throws</a> about the hierarchy.
--   
--   <ul>
--   <li><i><i>Subtyping</i></i> As there is no way to automatically infer
--   the subcases of an exception, they have to be encoded manually
--   mirroring the hierarchy defined in the defined <a>Exception</a>
--   instances. For example, the following instance encodes that
--   <tt>MyFileNotFoundException</tt> is a subexception of
--   <tt>MyIOException</tt> :</li>
--   </ul>
--   
--   <pre>
--   instance Throws MyFileNotFoundException (Caught MyIOException l)
--   </pre>
--   
--   <a>Throws</a> is not a transitive relation and every ancestor relation
--   must be explicitly encoded.
--   
--   <pre>
--                                                            --   TopException
--                                                            --         |
--   instance Throws MidException   (Caught TopException l)   --         |
--                                                            --   MidException
--   instance Throws ChildException (Caught MidException l)   --         |
--   instance Throws ChildException (Caught TopException l)   --         |
--                                                            --  ChildException
--   </pre>
--   
--   Note that <a>SomeException</a> is automatically an ancestor of every
--   other exception type.
class Exception e => Throws e l

-- | A type level witness of a exception handler.
data Caught e l

-- | The throw primitive
throw :: (Exception e, Throws e l, Monad m) => e -> EMT l m a

-- | Rethrow an exception keeping the call trace
rethrow :: (Throws e l, Monad m) => CallTrace -> e -> EMT l m a

-- | The catch primitive
catch :: (Exception e, Monad m) => EMT (Caught e l) m a -> (e -> EMT l m a) -> EMT l m a

-- | Catch and exception and observe the stack trace. If on top of the IO
--   monad, this will also capture asynchronous exceptions
catchWithSrcLoc :: (Exception e, Monad m) => EMT (Caught e l) m a -> (CallTrace -> e -> EMT l m a) -> EMT l m a

-- | Sequence two computations discarding the result of the second one. If
--   the first computation rises an exception, the second computation is
--   run and then the exception is rethrown.
finally :: Monad m => EMT l m a -> EMT l m b -> EMT l m a

-- | Like finally, but performs the second computation only when the first
--   one rises an exception TODO asynchronous exceptions! This needs to be
--   moved to Monad
onException :: Monad m => EMT l m a -> EMT l m b -> EMT l m a
bracket :: Monad m => EMT l m a -> (a -> EMT l m b) -> (a -> EMT l m c) -> EMT l m c

-- | Capture an exception e, wrap it, and rethrow. Keeps the original
--   monadic call trace.
wrapException :: (Exception e, Throws e' l, Monad m) => (e -> e') -> EMT (Caught e l) m a -> EMT l m a
showExceptionWithTrace :: Exception e => [String] -> e -> String

-- | <tt>FailException</tt> is thrown by Monad <a>fail</a>
data FailException
FailException :: String -> FailException

-- | <tt>MonadZeroException</tt> is thrown by MonadPlus <a>mzero</a>
data MonadZeroException
MonadZeroException :: MonadZeroException

-- | This function may be used as a value for <a>mplus</a> in
--   <a>MonadPlus</a>
mplusDefault :: Monad m => EMT l m a -> EMT l m a -> EMT l m a

-- | Any type that you wish to throw or catch as an exception must be an
--   instance of the <tt>Exception</tt> class. The simplest case is a new
--   exception type directly below the root:
--   
--   <pre>
--   data MyException = ThisException | ThatException
--       deriving Show
--   
--   instance Exception MyException
--   </pre>
--   
--   The default method definitions in the <tt>Exception</tt> class do what
--   we need in this case. You can now throw and catch
--   <tt>ThisException</tt> and <tt>ThatException</tt> as exceptions:
--   
--   <pre>
--   *Main&gt; throw ThisException `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   </pre>
--   
--   In more complicated examples, you may wish to define a whole hierarchy
--   of exceptions:
--   
--   <pre>
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e =&gt; SomeCompilerException e
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e =&gt; SomeFrontendException e
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving Show
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   </pre>
--   
--   We can now catch a <tt>MismatchedParentheses</tt> exception as
--   <tt>MismatchedParentheses</tt>, <tt>SomeFrontendException</tt> or
--   <tt>SomeCompilerException</tt>, but not other types, e.g.
--   <tt>IOException</tt>:
--   
--   <pre>
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   </pre>
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e

-- | Render this exception value in a human-friendly manner.
--   
--   Default implementation: <tt><a>show</a></tt>.
displayException :: Exception e => e -> String

-- | The <tt>SomeException</tt> type is the root of the exception type
--   hierarchy. When an exception of type <tt>e</tt> is thrown, behind the
--   scenes it is encapsulated in a <tt>SomeException</tt>.
data SomeException
SomeException :: e -> SomeException
class Monad f => Failure e (f :: Type -> Type)
failure :: Failure e f => e -> f v
instance (GHC.Exception.Type.Exception e, GHC.Base.Monad m) => Control.Monad.Exception.Catch.MonadCatch e (Control.Monad.Exception.Base.EMT (Control.Monad.Exception.Throws.Caught e l) m) (Control.Monad.Exception.Base.EMT l m)


-- | A Monad Transformer for explicitly typed checked exceptions, described
--   in detail by:
--   
--   <ul>
--   <li>Jose Iborra, "Explicitly Typed Exceptions for Haskell", PADL'10,
--   January 2010,
--   <a>http://dl.dropbox.com/s/lgm12trtl0swtra/PADL10.pdf?dl=1</a></li>
--   </ul>
--   
--   <a>Control.Monad.Exception.Pure</a> provides the classic, Either based
--   monad, whereas <a>Control.Monad.Exception.IO</a> provides a more
--   advanced IO based monad with the ability to handle asynchronous
--   exceptions as well.
module Control.Monad.Exception


-- | A monad transformer for explicitly typed checked exceptions with
--   support for asynchronous exception handling. Explicit exceptions are
--   supported by the ideas described in:
--   
--   <ul>
--   <li>Jose Iborra, "Explicitly Typed Exceptions for Haskell", PADL'10,
--   January 2010,
--   <a>http://dl.dropbox.com/s/lgm12trtl0swtra/PADL10.pdf?dl=1</a></li>
--   </ul>
--   
--   The exceptions thrown by a computation are inferred by the typechecker
--   and appear in the type signature of the computation as <a>Throws</a>
--   constraints.
--   
--   Support for asynchronous exceptions is provided by the monad-control
--   package.
--   
--   <i>Example</i>
--   
--   <pre>
--   data DivideByZero = DivideByZero deriving (Show, Typeable)
--   data SumOverflow  = SumOverflow  deriving (Show, Typeable)
--   </pre>
--   
--   <pre>
--   instance Exception DivideByZero
--   instance Exception SumOverflow
--   </pre>
--   
--   <pre>
--   data Expr = Add Expr Expr | Div Expr Expr | Val Double
--   </pre>
--   
--   <pre>
--   eval (Val x)     = return x
--   eval (Add a1 a2) = do
--      v1 &lt;- eval a1
--      v2 &lt;- eval a2
--      let sum = v1 + v2
--      if sum &lt; v1 || sum &lt; v2 then throw SumOverflow else return sum
--   eval (Div a1 a2) = do
--      v1 &lt;- eval a1
--      v2 &lt;- eval a2
--      if v2 == 0 then throw DivideByZero else return (v1 / v2)
--   </pre>
--   
--   GHCi infers the following types
--   
--   <pre>
--   eval                                             :: (Throws DivideByZero l, Throws SumOverflow l) =&gt; Expr -&gt; EM l Double
--   eval `catch` \ (e::DivideByZero) -&gt; return (-1)  :: Throws SumOverflow l =&gt; Expr -&gt; EM l Double
--   runEM(eval `catch` \ (e::SomeException) -&gt; return (-1))
--                                                    :: Expr -&gt; Double
--   </pre>
module Control.Monad.Exception.IO

-- | A monad of explicitly typed, checked exceptions
type EM l = EMT l Identity

-- | Run a computation explicitly handling exceptions
tryEM :: EM AnyException a -> Either SomeException a
tryEMWithLoc :: EM AnyException a -> Either (CallTrace, SomeException) a

-- | Run a safe computation
runEM :: EM NoExceptions a -> a

-- | Run a computation checking even unchecked
--   (<tt>UncaughtExceptions</tt>) exceptions
runEMParanoid :: EM ParanoidMode a -> a

-- | A Monad Transformer for explicitly typed checked exceptions.
newtype EMT l m a
EMT :: m (Either (CallTrace, CheckedException l) a) -> EMT l m a
[unEMT] :: EMT l m a -> m (Either (CallTrace, CheckedException l) a)
type CallTrace = [String]

-- | Run a computation explicitly handling exceptions
tryEMT :: Monad m => EMT AnyException m a -> m (Either SomeException a)
tryEMTWithLoc :: Monad m => EMT AnyException m a -> m (Either (CallTrace, SomeException) a)

-- | Run a safe computation
runEMT :: Monad m => EMT NoExceptions m a -> m a

-- | Run a safe computation checking even unchecked
--   (<a>UncaughtException</a>) exceptions
runEMTParanoid :: Monad m => EMT ParanoidMode m a -> m a
data AnyException

-- | UncaughtException models unchecked exceptions
--   
--   In order to declare an unchecked exception <tt>E</tt>, all that is
--   needed is to make <tt>e</tt> an instance of <a>UncaughtException</a>
--   
--   <pre>
--   instance UncaughtException E
--   </pre>
--   
--   Note that declaring an exception E as unchecked does not automatically
--   turn its children unchecked too. This is a shortcoming of the current
--   encoding.
class Exception e => UncaughtException e

-- | <tt>Throws</tt> is a type level binary relationship used to model a
--   list of exceptions.
--   
--   There is only one case in which the user must add further instances to
--   <tt>Throws</tt>. If your sets of exceptions are hierarchical then you
--   need to teach <a>Throws</a> about the hierarchy.
--   
--   <ul>
--   <li><i><i>Subtyping</i></i> As there is no way to automatically infer
--   the subcases of an exception, they have to be encoded manually
--   mirroring the hierarchy defined in the defined <a>Exception</a>
--   instances. For example, the following instance encodes that
--   <tt>MyFileNotFoundException</tt> is a subexception of
--   <tt>MyIOException</tt> :</li>
--   </ul>
--   
--   <pre>
--   instance Throws MyFileNotFoundException (Caught MyIOException l)
--   </pre>
--   
--   <a>Throws</a> is not a transitive relation and every ancestor relation
--   must be explicitly encoded.
--   
--   <pre>
--                                                            --   TopException
--                                                            --         |
--   instance Throws MidException   (Caught TopException l)   --         |
--                                                            --   MidException
--   instance Throws ChildException (Caught MidException l)   --         |
--   instance Throws ChildException (Caught TopException l)   --         |
--                                                            --  ChildException
--   </pre>
--   
--   Note that <a>SomeException</a> is automatically an ancestor of every
--   other exception type.
class Exception e => Throws e l

-- | A type level witness of a exception handler.
data Caught e l

-- | The throw primitive
throw :: (Exception e, Throws e l, Monad m) => e -> EMT l m a

-- | Rethrow an exception keeping the call trace
rethrow :: (Throws e l, Monad m) => CallTrace -> e -> EMT l m a

-- | The catch primitive
catch :: (Exception e, MonadBaseControl IO m) => EMT (Caught e l) m a -> (e -> EMT l m a) -> EMT l m a

-- | Catch and exception and observe the stack trace. If on top of the IO
--   monad, this will also capture asynchronous exceptions
catchWithSrcLoc :: (Exception e, MonadBaseControl IO m) => EMT (Caught e l) m a -> (CallTrace -> e -> EMT l m a) -> EMT l m a

-- | Sequence two computations discarding the result of the second one. If
--   the first computation rises an exception, the second computation is
--   run and then the exception is rethrown.
finally :: MonadBaseControl IO m => EMT l m a -> EMT l m b -> EMT l m a

-- | Like finally, but performs the second computation only when the first
--   one rises an exception
onException :: MonadBaseControl IO m => EMT l m a -> EMT l m b -> EMT l m a
bracket :: MonadBaseControl IO m => EMT l m a -> (a -> EMT l m b) -> (a -> EMT l m c) -> EMT l m c

-- | Capture an exception e, wrap it, and rethrow. Keeps the original
--   monadic call trace.
wrapException :: (Exception e, Throws e' l, MonadBaseControl IO m) => (e -> e') -> EMT (Caught e l) m a -> EMT l m a
showExceptionWithTrace :: Exception e => [String] -> e -> String

-- | <tt>FailException</tt> is thrown by Monad <a>fail</a>
data FailException
FailException :: String -> FailException

-- | <tt>MonadZeroException</tt> is thrown by MonadPlus <a>mzero</a>
data MonadZeroException
MonadZeroException :: MonadZeroException

-- | This function may be used as a value for <a>mplus</a> in
--   <a>MonadPlus</a>
mplusDefault :: Monad m => EMT l m a -> EMT l m a -> EMT l m a

-- | Any type that you wish to throw or catch as an exception must be an
--   instance of the <tt>Exception</tt> class. The simplest case is a new
--   exception type directly below the root:
--   
--   <pre>
--   data MyException = ThisException | ThatException
--       deriving Show
--   
--   instance Exception MyException
--   </pre>
--   
--   The default method definitions in the <tt>Exception</tt> class do what
--   we need in this case. You can now throw and catch
--   <tt>ThisException</tt> and <tt>ThatException</tt> as exceptions:
--   
--   <pre>
--   *Main&gt; throw ThisException `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   </pre>
--   
--   In more complicated examples, you may wish to define a whole hierarchy
--   of exceptions:
--   
--   <pre>
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e =&gt; SomeCompilerException e
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e =&gt; SomeFrontendException e
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving Show
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   </pre>
--   
--   We can now catch a <tt>MismatchedParentheses</tt> exception as
--   <tt>MismatchedParentheses</tt>, <tt>SomeFrontendException</tt> or
--   <tt>SomeCompilerException</tt>, but not other types, e.g.
--   <tt>IOException</tt>:
--   
--   <pre>
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   </pre>
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e

-- | Render this exception value in a human-friendly manner.
--   
--   Default implementation: <tt><a>show</a></tt>.
displayException :: Exception e => e -> String

-- | The <tt>SomeException</tt> type is the root of the exception type
--   hierarchy. When an exception of type <tt>e</tt> is thrown, behind the
--   scenes it is encapsulated in a <tt>SomeException</tt>.
data SomeException
SomeException :: e -> SomeException

-- | The class <a>Typeable</a> allows a concrete representation of a type
--   to be calculated.
class Typeable (a :: k)
class Monad f => Failure e (f :: Type -> Type)
failure :: Failure e f => e -> f v
instance (GHC.Exception.Type.Exception e, Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO m) => Control.Monad.Exception.Catch.MonadCatch e (Control.Monad.Exception.Base.EMT (Control.Monad.Exception.Throws.Caught e l) m) (Control.Monad.Exception.Base.EMT l m)
