packages feed

control-monad-exception 0.4.8 → 0.5

raw patch · 5 files changed

+291/−223 lines, 5 filesdep +control-monad-failuredep +monadlocdep −template-haskell

Dependencies added: control-monad-failure, monadloc

Dependencies removed: template-haskell

Files

Control/Monad/Exception.hs view
@@ -1,10 +1,8 @@ {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ExistentialQuantification, ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverlappingInstances #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE NamedFieldPuns #-}  {-| A Monad Transformer for explicitly typed checked exceptions.@@ -78,59 +76,86 @@  * If your sets of exceptions are hierarchical then you need to    teach 'Throws' about the hierarchy. ->                                                 --   TopException->                                                 --         |->   instance Throws MidException   TopException   --         |->                                                 --   MidException->   instance Throws ChildException MidException   --         |->   instance Throws ChildException TopException   --         |->                                                 --  ChildException+>                                                            --   TopException+>                                                            --         |+>   instance Throws MidException   (Caught TopException l)   --         |+>                                                            --   MidException+>   instance Throws ChildException (Caught MidException l)   --         |+>   instance Throws ChildException (Caught TopException l)   --         |+           >                                                 --  ChildException  - * Stack traces are only provided for explicitly annotated program points.-   For now there is the TH macro 'withLocTH' to help with this.-   Eventually a preprocessor could be written to automatically insert calls-   to 'withLoc' at every do statement.+ * Stack traces are provided via the "MonadLoc" package.+   All you need to do is add the following pragma at the top of your Haskell+   source files and use do-notation: ->       f () = $withLocTH $ throw MyException->       g a  = $withLocTH $ f a+>  {-# OPTIONS_GHC -F -pgmF MonadLoc #-}++   Only statements in do blocks appear in the stack trace.++* Example:++>       f () = do throw MyException+>       g a  = do f a >->       main = runEMT $ $withLocTH $ do->       g () `catchWithSrcLoc` \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)+>       main = runEMT $ do+>                g () `catchWithSrcLoc`+>                        \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)  >        -- Running main produces the output:  >       *Main> main >       MyException->        in Main(example.hs): (12,6)->           Main(example.hs): (11,7)-+>        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)  -} module Control.Monad.Exception (++-- * The EM monad     EM,  tryEM, runEM, runEMParanoid,-    EMT, tryEMT, runEMT, runEMTParanoid,-    WithSrcLoc(..), withLocTH,-    MonadZeroException(..),-    module Control.Monad.Exception.Class ) where +-- * The EMT monad transformer+    EMT, CallTrace, tryEMT, runEMT, runEMTParanoid,++-- * Exception primitives+    throw, rethrow, Control.Monad.Exception.catch, Control.Monad.Exception.catchWithSrcLoc,+    finally, onException, bracket, wrapException,++    showExceptionWithTrace,+    FailException(..), MonadZeroException(..),++-- * The Try class for absorbing other error monads+    Try(..), NothingException(..),++-- * Reexports+    Exception(..), SomeException(..), Typeable(..),+    MonadFailure(..),+    Throws, Caught, UncaughtException,+    withLoc, withLocTH,++) where+ import Control.Applicative+import qualified Control.Exception as CE import Control.Monad.Identity-import Control.Monad.Exception.Class+import Control.Monad.Exception.Catch import Control.Monad.Fix import Control.Monad.Trans import Control.Monad.Cont.Class import Control.Monad.RWS.Class+import Control.Monad.Loc+import Control.Monad.Failure import Data.Monoid import Data.Typeable-import Language.Haskell.TH.Syntax hiding (lift) import Text.PrettyPrint import Prelude hiding (catch)  -- | A monad of explicitly typed, checked exceptions type EM l = EMT l Identity - mapLeft :: (a -> b) -> Either a r -> Either b r mapLeft f (Left x)  = Left (f x) mapLeft _ (Right x) = Right x@@ -147,21 +172,21 @@ runEMParanoid :: EM ParanoidMode a -> a runEMParanoid = runIdentity . runEMTParanoid -data MonadZeroException = MonadZeroException deriving (Show, Typeable)-instance Exception MonadZeroException+type CallTrace = [String] -newtype EMT l m a = EMT {unEMT :: m (Either ([String], WrapException l) a)}+newtype EMT l m a = EMT {unEMT :: m (Either (CallTrace, CheckedException l) a)}  type AnyException = Caught SomeException  -- | Run a computation explicitly handling exceptions tryEMT :: Monad m => EMT (AnyException l) m a -> m (Either SomeException a)-tryEMT (EMT m) = mapLeft (unwrapException.snd) `liftM` m+tryEMT (EMT m) = mapLeft (checkedException.snd) `liftM` m -runEMT_gen :: Monad m => EMT l m a -> m a-runEMT_gen (EMT m) = liftM f m where-  f (Right x) = x-  f (Left (loc,e)) = error (showExceptionWithTrace loc (unwrapException e))+runEMT_gen :: forall l m a . Monad m => EMT l m a -> m a+runEMT_gen (EMT m) = m >>= \x ->+                     case x of+                       Right x -> return x+                       Left (loc,e) -> error (showExceptionWithTrace loc (checkedException e))  -- | Run a safe computation runEMT :: Monad m => EMT NoExceptions m a -> m a@@ -180,6 +205,9 @@  instance Monad m => Monad (EMT l m) where   return = EMT . return . Right++  fail s = EMT $ return $ Left ([], CheckedException $ toException $ FailException s)+   emt >>= f = EMT $ do                 v <- unEMT emt                 case v of@@ -190,52 +218,77 @@   pure  = return   (<*>) = ap -instance (Exception e, Throws e l, Monad m) => MonadThrow e (EMT l m) where-  throw = EMT . return . (\e -> Left ([],e)) . WrapException . toException+instance (Exception e, Throws e l, Monad m) => MonadFailure e (EMT l m) where+  failure = throw+ instance (Exception e, Monad m) => MonadCatch e (EMT (Caught e l) m) (EMT l m) where-  catchWithSrcLoc = catchEMT-  catch emt h = catchEMT emt (\_ -> h)+  catchWithSrcLoc = Control.Monad.Exception.catchWithSrcLoc+  catch           = Control.Monad.Exception.catch -catchEMT :: (Exception e, Monad m) => EMT (Caught e l) m a -> ([String] -> e -> EMT l m a) -> EMT l m a-catchEMT emt h = EMT $ do+instance Monad m => MonadLoc (EMT l m) where+    withLoc loc (EMT emt) = EMT $ do+                     current <- emt+                     case current of+                       (Left (tr, a)) -> return (Left (loc:tr, a))+                       _              -> return current++-- | The throw primitive+throw :: (Exception e, Throws e l, Monad m) => e -> EMT l m a+throw = EMT . return . (\e -> Left ([],e)) . CheckedException . toException++-- | Rethrow an exception keeping the call trace+rethrow :: (Throws e l, Monad m) => CallTrace -> e -> EMT l m a+rethrow callt = EMT . return . (\e -> Left (callt,e)) . CheckedException . toException+++-- | The catch primitive+catch :: (Exception e, Monad m) => EMT (Caught e l) m a -> (e -> EMT l m a) -> EMT l m a+catch emt h = Control.Monad.Exception.catchWithSrcLoc emt (\_ -> h)++-- | Like 'Control.Monad.Exception.catch' but makes the call trace available+catchWithSrcLoc :: (Exception e, Monad m) => EMT (Caught e l) m a -> (CallTrace -> e -> EMT l m a) -> EMT l m a+catchWithSrcLoc emt h = EMT $ do                 v <- unEMT emt                 case v of                   Right x -> return (Right x)-                  Left (trace, WrapException e) -> case fromException e of-                               Nothing -> return (Left (trace,WrapException e))+                  Left (trace, CheckedException e) -> case fromException e of+                               Nothing -> return (Left (trace,CheckedException e))                                Just e' -> unEMT (h trace e') --- | 'withLocTH' is a convenient TH macro which expands to 'withLoc' @\<source location\>@---   Usage:------  > f x = $withLocTH $ do-withLocTH :: Q Exp-withLocTH = do-  loc <- qLocation-  let loc_msg = showLoc loc-  [| withLoc loc_msg |]- where-   showLoc Loc{loc_module, loc_filename, loc_start} = render $-                     {- text loc_package <> char '.' <> -}-                     text loc_module <> parens (text loc_filename) <> colon <+> text (show loc_start) --- | Generating stack traces for exceptions-class WithSrcLoc a where-  -- | 'withLoc' records the given source location in the exception stack trace-  --   when used to wrap a EMT computation.-  ---  --   On any other monad or value, 'withLoc' is defined as the identity-  withLoc :: String -> a -> 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+finally m sequel = do { v <- m `onException` sequel; sequel; return v} -instance WithSrcLoc a where withLoc _ = id -instance Monad m => WithSrcLoc (EMT l m a) where-    withLoc loc (EMT emt) = EMT $ do-                     current <- emt-                     case current of-                       (Left (tr, a)) -> return (Left (loc:tr, a))-                       _              -> return current+-- | Like finally, but performs the second computation only when the first one+--   rises an exception+onException :: Monad m => EMT l m a -> EMT l m b -> EMT l m a+onException (EMT m) (EMT sequel) = EMT $ do+                                     ev <- m+                                     case ev of+                                       Left{}  -> do { sequel; return ev}+                                       Right{} -> return ev +bracket :: Monad m => EMT l m a        -- ^ acquire resource+                   -> (a -> EMT l m b) -- ^ release resource+                   -> (a -> EMT l m c) -- ^ computation+                   -> EMT l m c+bracket acquire release run = do { k <- acquire; run k `finally` release k }++-- | Capture an exception e, wrap it, and rethrow.+--   Keeps the original monadic call trace.+wrapException :: (Exception e, Throws e' l, Monad m) => EMT (Caught e l) m a -> (e -> e') -> EMT l m a+wrapException m mkE = m `Control.Monad.Exception.catchWithSrcLoc` \loc e -> rethrow loc (mkE e)++showExceptionWithTrace :: Exception e => [String] -> e -> String+showExceptionWithTrace [] e = show e+showExceptionWithTrace trace e = render$+             text (show e) $$+             text " in" <+> (vcat (map text $ reverse trace))+ instance (Throws MonadZeroException l) => MonadPlus (EM l) where   mzero = throw MonadZeroException   mplus emt1 emt2 = EMT$ do@@ -250,9 +303,42 @@   mfix f = EMT $ mfix $ \a -> unEMT $ f $ case a of                                              Right r -> r                                              _       -> error "empty fix argument"+instance UncaughtException SomeException  instance (Throws SomeException l, MonadIO m) => MonadIO (EMT l m) where-  liftIO = lift . liftIO+  liftIO m = EMT (liftIO m') where+      m' = liftM Right m+            `CE.catch`+           \(e::SomeException) -> return (Left ([], CheckedException e))+++-- -----------------------------------------------+-- The Try class for absorbing other error monads+-- -----------------------------------------------+data NothingException = NothingException deriving (Typeable, Show)+instance Exception NothingException++class Try m l where try :: Monad m' => m a -> EMT l m' a+instance Throws NothingException l => Try Maybe l where try = maybe (throw NothingException) return+instance (Exception e, Throws e l) => Try (Either e) l where try = either throw return++instance (Monad m, Try m l) => Try (EMT l m) l where try = join . fmap (EMT . return) .try . unEMT++-- -----------+-- Exceptions+-- -----------++-- | @FailException@ is thrown by Monad 'fail'+data FailException = FailException String deriving (Show, Typeable)+instance Exception FailException++-- | @MonadZeroException@ is thrown by MonadPlus 'mzero'+data MonadZeroException = MonadZeroException deriving (Show, Typeable)+instance Exception MonadZeroException++-- ------------------+-- mtl boilerplate+-- ------------------  instance MonadCont m => MonadCont (EMT l m) where   callCC f = EMT $ callCC $ \c -> unEMT (f (\a -> EMT $ c (Right a)))
+ Control/Monad/Exception/Catch.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE OverlappingInstances #-}+++{-| Defines the (not so useful anymore) 'MonadCatch' type class.+-}++module Control.Monad.Exception.Catch (+       module Control.Monad,+       module Control.Monad.Exception.Throws,+       MonadCatch(..),+       Exception(..), SomeException(..),+       ) where++import Control.Monad+#if TRANSFORMERS+import Control.Monad.Trans.Error+import Control.Monad.Trans.List+import Control.Monad.Trans.Reader+import Control.Monad.Trans.State+import Control.Monad.Trans.Writer+import Control.Monad.Trans.RWS+#else+import Control.Monad.Error+import Control.Monad.List+import Control.Monad.Reader+import Control.Monad.State+import Control.Monad.Writer+import Control.Monad.RWS+#endif++#if __GLASGOW_HASKELL__ < 610+import Control.Exception.Extensible (Exception(..), SomeException)+import qualified Control.Exception.Extensible as Control.Exception+#else+import Control.Exception (Exception(..), SomeException)+import qualified Control.Exception+#endif+import Data.Monoid++import Control.Monad.Exception.Throws++import Prelude hiding (catch)++class (Monad m, Monad m') => MonadCatch e m m' | e m -> m', e m' -> m where+   catch   :: m a -> (e -> m' a) -> m' a+   catchWithSrcLoc :: m a -> ([String] -> e -> m' a) -> m' a+   catchWithSrcLoc m h = catch m (h [])++instance Exception e => MonadCatch e IO IO where+   catch   = Control.Exception.catch++-- Throw and Catch instances for the Either and ErrorT monads+-- -----------------------------------------------------------+instance (Error e) => MonadCatch e (Either e) (Either e) where catch m h = either h Right m+instance (Error e, Monad m) => MonadCatch e (ErrorT e m) (ErrorT e m) where catch = catchError+++-- Instances for transformers (requires undecidable instances in some cases)+-- -------------------------------------------------------------------------+instance MonadCatch e m m' => MonadCatch e (ListT m) (ListT m') where catch (ListT m) h = ListT (catch m (runListT . h))+instance MonadCatch e m m' => MonadCatch e (ReaderT r m) (ReaderT r m') where catch (ReaderT m) h = ReaderT (\s -> catch (m s) ((`runReaderT` s) . h))++instance (Monoid w, MonadCatch e m m') => MonadCatch e (WriterT w m) (WriterT w m') where catch (WriterT m) h = WriterT (catch m (runWriterT . h))++instance MonadCatch e m m' => MonadCatch e (StateT s m) (StateT s m') where catch (StateT m) h = StateT (\s -> catch (m s) ((`runStateT` s) . h))++instance (Monoid w, MonadCatch e m m') => MonadCatch e (RWST r w s m) (RWST r w s m') where catch (RWST m) h = RWST (\r s -> catch (m r s) ((\m -> runRWST m r s) . h))
− Control/Monad/Exception/Class.hs
@@ -1,120 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE OverlappingInstances #-}---{-| Defines 'MonadThrow' and 'MonadCatch' type classes and suitable instances for 'IO' and 'Either'.--}--module Control.Monad.Exception.Class (-       module Control.Monad,-       module Control.Monad.Exception.Throws,-       MonadThrow(..), MonadCatch(..),-       WrapException(..), Exception(..), SomeException(..),-       showExceptionWithTrace, wrapException-       ) where--import Control.Monad-#if TRANSFORMERS-import Control.Monad.Trans-import Control.Monad.Trans.Error-import Control.Monad.Trans.List-import Control.Monad.Trans.Reader-import Control.Monad.Trans.State-import Control.Monad.Trans.Writer-import Control.Monad.Trans.RWS-#else-import Control.Monad.Error-import Control.Monad.List-import Control.Monad.Reader-import Control.Monad.State-import Control.Monad.Writer-import Control.Monad.RWS-#endif--#if __GLASGOW_HASKELL__ < 610-import Control.Exception.Extensible (Exception(..), SomeException)-import qualified Control.Exception.Extensible as Control.Exception-#else-import Control.Exception (Exception(..), SomeException)-import qualified Control.Exception-#endif-import Data.Monoid-import Data.Typeable-import Text.PrettyPrint--import Control.Monad.Exception.Throws--import Prelude hiding (catch)--class Monad m => MonadThrow e m where-    throw :: e -> m a-    throwWithSrcLoc :: String -> e -> m a-    throwWithSrcLoc _ = throw--instance Exception e => MonadThrow e IO where-   throw = Control.Exception.throw--class (Monad m, Monad m') => MonadCatch e m m' | e m -> m', e m' -> m where-   catch   :: m a -> (e -> m' a) -> m' a-   catchWithSrcLoc :: m a -> ([String] -> e -> m' a) -> m' a-   catchWithSrcLoc m h = catch m (h [])--instance Exception e => MonadCatch e IO IO where-   catch   = Control.Exception.catch--wrapException ::-     (MonadThrow e' m', MonadCatch e m m') =>-     m a -> (e -> e') -> m' a-wrapException m mkE = m `catch` (throw . mkE)--{-| Given a list of source locations and an exception, @showExceptionWithTrace@ produces output of the form-->       <exception details>->        in <module a>(<file a.hs>): (12,6)->           <module b>(<file b.hs>): (11,7)->           ...---}-showExceptionWithTrace :: Exception e => [String] -> e -> String-showExceptionWithTrace trace e = render$-             text (show e) $$-             text " in" <+> (vcat (map text $ reverse trace))---- Labelled SomeException--- --------------------------- | @WrapException@ adds a phantom type parameter @l@ to @SomeException@-newtype WrapException l = WrapException {unwrapException::SomeException} deriving (Typeable)-instance Show (WrapException l) where show (WrapException e) = show e---- Throw and Catch instances for the Either and ErrorT monads--- ------------------------------------------------------------instance (Error e) => MonadThrow e (Either e) where throw = Left-instance (Error e) => MonadCatch e (Either e) (Either e) where catch m h = either h Right m--instance (Error e, Monad m) => MonadThrow e (ErrorT e m) where throw = throwError-instance (Error e, Monad m) => MonadCatch e (ErrorT e m) (ErrorT e m) where catch = catchError----- Instances for transformers (requires undecidable instances in some cases)--- --------------------------------------------------------------------------instance MonadThrow e m    => MonadThrow e (ListT m)            where throw = lift . throw-instance MonadCatch e m m' => MonadCatch e (ListT m) (ListT m') where catch (ListT m) h = ListT (catch m (runListT . h))--instance MonadThrow e m    => MonadThrow e (ReaderT r m)                where throw = lift . throw-instance MonadCatch e m m' => MonadCatch e (ReaderT r m) (ReaderT r m') where catch (ReaderT m) h = ReaderT (\s -> catch (m s) ((`runReaderT` s) . h))--instance (Monoid w, MonadThrow e m)    => MonadThrow e (WriterT w  m)               where throw = lift . throw-instance (Monoid w, MonadCatch e m m') => MonadCatch e (WriterT w m) (WriterT w m') where catch (WriterT m) h = WriterT (catch m (runWriterT . h))--instance MonadThrow e m    => MonadThrow e (StateT s m)               where throw = lift . throw-instance MonadCatch e m m' => MonadCatch e (StateT s m) (StateT s m') where catch (StateT m) h = StateT (\s -> catch (m s) ((`runStateT` s) . h))--instance (Monoid w, MonadThrow e m)    => MonadThrow e (RWST r w s m)                 where throw = lift . throw-instance (Monoid w, MonadCatch e m m') => MonadCatch e (RWST r w s m) (RWST r w s m') where catch (RWST m) h = RWST (\r s -> catch (m r s) ((\m -> runRWST m r s) . h))
Control/Monad/Exception/Throws.hs view
@@ -2,19 +2,24 @@ {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverlappingInstances, FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}  {-| Defines the @Throws@ binary relationship between types. -} -module Control.Monad.Exception.Throws (Throws, Caught, UncaughtException, NoExceptions, ParanoidMode) where+module Control.Monad.Exception.Throws (+    Throws, Caught,+    CheckedException(..),+    UncaughtException,+    NoExceptions, ParanoidMode) where  #if __GLASGOW_HASKELL__ < 610 import Control.Exception.Extensible (Exception(..), SomeException) #else import Control.Exception (Exception(..), SomeException) #endif-+import Data.Typeable  -- | A type level witness of a exception handler. data Caught e l@@ -45,18 +50,17 @@    'Throws' is not a transitive relation and every ancestor relation    must be explicitly encoded. ->                                                 --   TopException->                                                 --         |->   instance Throws MidException   TopException   --         |->                                                 --   MidException->   instance Throws ChildException MidException   --         |->   instance Throws ChildException TopException   --         |->                                                 --  ChildException+>                                                            --   TopException+>                                                            --         |+>   instance Throws MidException   (Caught TopException l)   --         |+>                                                            --   MidException+>   instance Throws ChildException (Caught MidException l)   --         |+>   instance Throws ChildException (Caught TopException l)   --         |+>                                                            --  ChildException  'SomeException' is automatically    an ancestor of every other exception type. - -}  class (Private l, Exception e) => Throws e l@@ -68,17 +72,37 @@ --   . --   Capturing SomeException captures every possible exception instance Exception e => Throws e (Caught SomeException l)+instance Throws SomeException (Caught SomeException l) -- Disambiguation instance  -- | Uncaught Exceptions model unchecked exceptions (a la RuntimeException in Java) -----   In order to declare an unchecked exception @e@,+--   In order to declare an unchecked exception @E@, --   all that is needed is to make @e@ an instance of @UncaughtException@+--+--  > instance UncaughtException E+--+--   Note that declaring an exception E as unchecked does not automatically+--   turn its children as unchecked too. This is a shortcoming of the current encoding.+{-+--   If that is what you want, then+--   declare E as unchecked using an instance of @Throws@:+--+--  > instance Throws E l+--+--  The shortcoming of this route is that runEMTParanoid won't be able to+--  control exceptions declared unchecked this way.+-} class Exception e => UncaughtException e instance UncaughtException e => Throws e NoExceptions - data NoExceptions instance Private NoExceptions  data ParanoidMode instance Private ParanoidMode++-- Labelled SomeException+-- ------------------------+-- | @CheckedException@ adds a phantom type parameter @l@ to @SomeException@+newtype CheckedException l = CheckedException {checkedException::SomeException} deriving (Typeable)+instance Show (CheckedException l) where show (CheckedException e) = show e
control-monad-exception.cabal view
@@ -1,5 +1,5 @@ name: control-monad-exception-version: 0.4.8+version: 0.5 Cabal-Version:  >= 1.2.3 build-type: Simple license: PublicDomain@@ -38,27 +38,29 @@   > runEM(eval `catch` \ (e::SomeException) -> return (-1))  :: Expr -> Double   .   .-  This package provides, among other things:+  In addition to explicitly typed exceptions his package provides:   .     * Support for explicitly documented, unchecked exceptions (with 'tryEM').   .     * Support for selective unchecked exceptions (with 'UncaughtException').   .-    * Support for exception stack traces (experimental). /Example:/+    * Support for exception call traces via 'Control.Monad.Loc.MonadLoc'. /Example:/   .-  >       f () = $withLocTH $ throw MyException-  >       g a  = $withLocTH $ f a   >-  >       main = runEMT $ $withLocTH $ do-  >       g () `catchWithSrcLoc` \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)-  .-  >        -- Running main produces the output:-  .-  >       *Main> main-  >       MyException-  >        in Main(example.hs): (12,6)-  >           Main(example.hs): (11,7)-  .+  > f () = do throw MyException+  > g a  = do f a+  >+  > main = runEMT $ do g () `catchWithSrcLoc`+  >                        \loc (e::MyException) -> lift(putStrLn$ showExceptionWithTrace loc e)+  >+  > -- Running main produces the output:+  >+  > *Main> 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)  synopsis: Explicitly typed, checked exceptions with stack traces category: Control, Monads@@ -76,7 +78,9 @@   default: False  Library-  buildable: True+  buildable: True +  build-depends: control-monad-failure, monadloc, pretty+   if flag(extensibleExceptions)     build-depends:       extensible-exceptions >= 0.1 && <0.2,@@ -99,9 +103,9 @@                EmptyDataDecls,                DeriveDataTypeable,                UndecidableInstances-  build-depends: pretty, template-haskell+   exposed-modules:-     Control.Monad.Exception.Class+     Control.Monad.Exception.Catch      Control.Monad.Exception.Throws      Control.Monad.Exception-  ghc-options: -Wall -fno-warn-name-shadowing+  ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-orphans