control-monad-exception 0.1.2 → 0.2
raw patch · 3 files changed
+86/−52 lines, 3 filesdep +extensible-exceptionsdep ~basedep ~monads-fddep ~transformersPVP ok
version bump matches the API change (PVP)
Dependencies added: extensible-exceptions
Dependency ranges changed: base, monads-fd, transformers
API changes (from Hackage documentation)
- Control.Monad.Exception: EM :: Either SomeException a -> EM l a
- Control.Monad.Exception: MonadZero :: MonadZero
- Control.Monad.Exception: data MonadZero
- Control.Monad.Exception: instance [overlap ok] (Exception e) => MonadCatch e (EM (Caught e l)) (EM l)
- Control.Monad.Exception: instance [overlap ok] (Exception e, Throws e l) => MonadThrow e (EM l)
- Control.Monad.Exception: instance [overlap ok] (Monad m, Throws MonadZero l) => MonadPlus (EMT l m)
- Control.Monad.Exception: instance [overlap ok] (MonadIO m) => MonadIO (EMT l m)
- Control.Monad.Exception: instance [overlap ok] (Throws MonadZero l) => MonadPlus (EM l)
- Control.Monad.Exception: instance [overlap ok] Exception MonadZero
- Control.Monad.Exception: instance [overlap ok] Functor (EM l)
- Control.Monad.Exception: instance [overlap ok] Monad (EM l)
- Control.Monad.Exception: instance [overlap ok] Show MonadZero
- Control.Monad.Exception: instance [overlap ok] Typeable MonadZero
- Control.Monad.Exception: newtype EM l a
- Control.Monad.Exception: unEM :: EM l a -> Either SomeException a
+ Control.Monad.Exception: MonadZeroException :: MonadZeroException
+ Control.Monad.Exception: data MonadZeroException
+ Control.Monad.Exception: instance [overlap ok] (Monad m, Throws MonadZeroException l) => MonadPlus (EMT l m)
+ Control.Monad.Exception: instance [overlap ok] (Throws SomeException l, MonadIO m) => MonadIO (EMT l m)
+ Control.Monad.Exception: instance [overlap ok] Exception MonadZeroException
+ Control.Monad.Exception: instance [overlap ok] Show MonadZeroException
+ Control.Monad.Exception: instance [overlap ok] Typeable MonadZeroException
+ Control.Monad.Exception: type EM l = EMT l Identity
+ Control.Monad.Exception.Class: WrapException :: SomeException -> WrapException l
+ Control.Monad.Exception.Class: instance [overlap ok] Show (WrapException l)
+ Control.Monad.Exception.Class: newtype WrapException l
+ Control.Monad.Exception.Class: wrapException :: WrapException l -> SomeException
- Control.Monad.Exception: EMT :: m (Either SomeException a) -> EMT l m a
+ Control.Monad.Exception: EMT :: m (Either (WrapException l) a) -> EMT l m a
- Control.Monad.Exception: unEMT :: EMT l m a -> m (Either SomeException a)
+ Control.Monad.Exception: unEMT :: EMT l m a -> m (Either (WrapException l) a)
Files
- Control/Monad/Exception.hs +26/−44
- Control/Monad/Exception/Class.hs +41/−6
- control-monad-exception.cabal +19/−2
Control/Monad/Exception.hs view
@@ -1,67 +1,49 @@-+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} module Control.Monad.Exception (- module Control.Monad.Exception,+ EM, evalEM, runEM,+ EMT(..), evalEMT, runEMT,+ MonadZeroException(..), module Control.Monad.Exception.Class ) where +import Control.Monad.Identity import Control.Monad.Exception.Class import Control.Monad.Fix import Control.Monad.Trans import Control.Monad.Cont.Class-import Control.Monad.Reader.Class-import Control.Monad.State.Class-import Control.Monad.Writer.Class import Control.Monad.RWS.Class import Data.Monoid import Data.Typeable import Prelude hiding (catch) -newtype EM l a = EM {unEM::Either SomeException a}+type EM l = EMT l Identity -- | Run a computation which may fail evalEM :: EM (Caught SomeException l) a -> Either SomeException a-evalEM (EM a) = a+evalEM (EMT a) = mapLeft wrapException (runIdentity a) +mapLeft :: (a -> b) -> Either a r -> Either b r+mapLeft f (Left x) = Left (f x)+mapLeft _ (Right x) = Right x+ -- | Run a safe computation runEM :: EM l a -> a-runEM (EM (Right a)) = a-runEM _ = error "evalEM : The impossible happened"--instance Functor (EM l) where- fmap f (EM (Left e)) = EM (Left e)- fmap f (EM (Right x)) = EM (Right (f x))--instance Monad (EM l) where- return = EM . Right- EM (Right x) >>= f = f x- EM (Left e) >>= _ = EM (Left e)--instance (Exception e, Throws e l) => MonadThrow e (EM l) where- throw = EM . Left . toException-instance Exception e => MonadCatch e (EM (Caught e l)) (EM l) where- catch (EM(Right x)) h = EM (Right x)- catch (EM(Left e)) h = case fromException e of- Nothing -> EM (Left e)- Just e' -> h e'--data MonadZero = MonadZero deriving (Show, Typeable)-instance Exception MonadZero-+runEM = runIdentity . runEMT --- Requires undecidable instances-instance Throws MonadZero l => MonadPlus (EM l) where- mzero = throw MonadZero- mplus (EM (Left _)) p2 = p2- mplus p1@(EM Right{}) p2 = p1+data MonadZeroException = MonadZeroException deriving (Show, Typeable)+instance Exception MonadZeroException -newtype EMT l m a = EMT {unEMT :: m (Either SomeException a)}+newtype EMT l m a = EMT {unEMT :: m (Either (WrapException l) a)} evalEMT :: Monad m => EMT (Caught SomeException l) m a -> m (Either SomeException a)-evalEMT (EMT m) = m+evalEMT (EMT m) = mapLeft wrapException `liftM` m runEMT :: Monad m => EMT l m a -> m a runEMT (EMT m) = liftM f m where f (Right x) = x- f (Left x) = error "evalEMT: The impossible happened"+ f (Left _) = error "evalEMT: The impossible happened" instance Monad m => Functor (EMT l m) where fmap f emt = EMT $ do@@ -79,19 +61,19 @@ Right x -> unEMT (f x) instance (Exception e, Throws e l, Monad m) => MonadThrow e (EMT l m) where- throw = EMT . return . Left . toException+ throw = EMT . return . Left . WrapException . toException instance (Exception e, Monad m) => MonadCatch e (EMT (Caught e l) m) (EMT l m) where catch emt h = EMT $ do v <- unEMT emt case v of Right x -> return (Right x)- Left e -> case fromException e of- Nothing -> return (Left e)+ Left (WrapException e) -> case fromException e of+ Nothing -> return (Left (WrapException e)) Just e' -> unEMT (h e') -instance (Monad m, Throws MonadZero l) => MonadPlus (EMT l m) where- mzero = throw MonadZero+instance (Monad m, Throws MonadZeroException l) => MonadPlus (EMT l m) where+ mzero = throw MonadZeroException mplus emt1 emt2 = EMT$ do v1 <- unEMT emt1 case v1 of@@ -105,7 +87,7 @@ Right r -> r _ -> error "empty fix argument" -instance MonadIO m => MonadIO (EMT l m) where+instance (Throws SomeException l, MonadIO m) => MonadIO (EMT l m) where liftIO = lift . liftIO instance MonadCont m => MonadCont (EMT l m) where
Control/Monad/Exception/Class.hs view
@@ -1,7 +1,14 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-} module Control.Monad.Exception.Class ( module Control.Monad,- module Control.Monad.Exception.Class,- Exception(..), SomeException) where+ MonadThrow(..), MonadCatch(..),+ Throws, Caught,+ WrapException(..), Exception(..), SomeException) where import Control.Monad import Control.Monad.Trans@@ -11,11 +18,29 @@ import Control.Monad.Trans.State import Control.Monad.Trans.Writer import Control.Monad.Trans.RWS+#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 Prelude hiding (catch) +{-| @Throws@ is the mechanism used to keep a type level+ list of exceptions.+ .+ Usually there is no need for the user of this library+ to add further instances to @Throws@ except in one+ case: to encode subtyping. For instance if we have+ an @IOException@ type and a @FIleNotFoundException@ subcase,+ we need to add the instance:++ > instance Throws FileNotFoundException (Caught IOException l)++-}+ class Exception e => Throws e s class Monad m => MonadThrow e m where@@ -25,27 +50,37 @@ 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+ catch :: m a -> (e -> m' a) -> m' a instance Exception e => MonadCatch e IO IO where- catch = Control.Exception.catch+ catch = Control.Exception.catch +-- | A type level witness of a exception handler. data Caught e l instance Exception e => Throws e (Caught e l) instance Throws e l => Throws e (Caught e1 l)+-- | @SomeException@ is at the top of the exception hierarchy+-- .+-- Capturing SomeException captures every possible exception instance Exception e => Throws e (Caught SomeException l) --- Throw and Catch instances for the Either and ErrorT monads+-- Labelled SomeException+-- ------------------------+newtype WrapException l = WrapException {wrapException::SomeException} deriving Show ++-- 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) +-- 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))
control-monad-exception.cabal view
@@ -1,5 +1,5 @@ name: control-monad-exception-version: 0.1.2+version: 0.2 Cabal-Version: >= 1.2.3 build-type: Simple license: PublicDomain@@ -37,11 +37,27 @@ synopsis: Explicitly typed exceptions category: Control, Monads stability: experimental+tested-with: GHC ==6.8.2+tested-with: GHC ==6.10.2+tested-with: GHC ==6.10.3 +Flag extensibleExceptions+ description: Use extensible-exception package+ default: False Library buildable: True- build-depends: base >= 4.0, transformers, monads-fd+ if flag(extensibleExceptions)+ build-depends:+ extensible-exceptions >= 0.1 && <0.2,+ base >= 3.0 && <4+ else+ build-depends:+ base >= 4.0++ build-depends:+ transformers >= 0.0.1 && <0.2,+ monads-fd >= 0.0 && <0.1 extensions: MultiParamTypeClasses, FunctionalDependencies, OverlappingInstances, @@ -52,3 +68,4 @@ exposed-modules: Control.Monad.Exception.Class Control.Monad.Exception+ ghc-options: -Wall -fno-warn-name-shadowing