control-monad-exception 0.2 → 0.3
raw patch · 3 files changed
+66/−20 lines, 3 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Control.Monad.Exception: evalEM :: EM (Caught SomeException l) a -> Either SomeException a
- Control.Monad.Exception.Class: instance [overlap ok] (Throws e l) => Throws e (Caught e1 l)
+ Control.Monad.Exception: instance [overlap ok] (Monad m) => Applicative (EMT l m)
+ Control.Monad.Exception: runEMTParanoid :: (Monad m) => EMT ParanoidMode m a -> m a
+ Control.Monad.Exception.Class: SomeException :: e -> SomeException
+ Control.Monad.Exception.Class: class (Exception e) => UncaughtException e
+ Control.Monad.Exception.Class: data NoExceptions
+ Control.Monad.Exception.Class: data ParanoidMode
+ Control.Monad.Exception.Class: instance [overlap ok] (Throws e l) => Throws e (Caught e' l)
+ Control.Monad.Exception.Class: instance [overlap ok] (UncaughtException e) => Throws e NoExceptions
+ Control.Monad.Exception.Class: instance [overlap ok] Private (Caught e l)
+ Control.Monad.Exception.Class: instance [overlap ok] Private NoExceptions
+ Control.Monad.Exception.Class: instance [overlap ok] Private ParanoidMode
- Control.Monad.Exception: runEM :: EM l a -> a
+ Control.Monad.Exception: runEM :: EM NoExceptions a -> a
- Control.Monad.Exception: runEMT :: (Monad m) => EMT l m a -> m a
+ Control.Monad.Exception: runEMT :: (Monad m) => EMT NoExceptions m a -> m a
- Control.Monad.Exception.Class: class (Exception e) => Throws e s
+ Control.Monad.Exception.Class: class (Private l, Exception e) => Throws e l
Files
- Control/Monad/Exception.hs +32/−9
- Control/Monad/Exception/Class.hs +29/−6
- control-monad-exception.cabal +5/−5
Control/Monad/Exception.hs view
@@ -2,12 +2,15 @@ {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverlappingInstances #-}+ module Control.Monad.Exception (- EM, evalEM, runEM,- EMT(..), evalEMT, runEMT,+ EM, runEM,+ EMT(..), evalEMT, runEMT, runEMTParanoid, MonadZeroException(..), module Control.Monad.Exception.Class ) where +import Control.Applicative import Control.Monad.Identity import Control.Monad.Exception.Class import Control.Monad.Fix@@ -20,16 +23,22 @@ type EM l = EMT l Identity ++{-+data AnyException++instance Exception e => Throws e AnyException+ -- | Run a computation which may fail-evalEM :: EM (Caught SomeException l) a -> Either SomeException a+evalEM :: EM AnyException a -> Either SomeException 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 NoExceptions a -> a runEM = runIdentity . runEMT data MonadZeroException = MonadZeroException deriving (Show, Typeable)@@ -40,11 +49,18 @@ evalEMT :: Monad m => EMT (Caught SomeException l) m a -> m (Either SomeException a) evalEMT (EMT m) = mapLeft wrapException `liftM` m -runEMT :: Monad m => EMT l m a -> m a-runEMT (EMT m) = liftM f m where+runEMT_gen :: Monad m => EMT l m a -> m a+runEMT_gen (EMT m) = liftM f m where f (Right x) = x- f (Left _) = error "evalEMT: The impossible happened"+ f (Left (WrapException (SomeException e))) = error (show e) +runEMT :: Monad m => EMT NoExceptions m a -> m a+runEMT = runEMT_gen++-- | Check even runtime (@UncaughtException@) exceptions+runEMTParanoid :: Monad m => EMT ParanoidMode m a -> m a+runEMTParanoid = runEMT_gen+ instance Monad m => Functor (EMT l m) where fmap f emt = EMT $ do v <- unEMT emt@@ -60,10 +76,17 @@ Left e -> return (Left e) Right x -> unEMT (f x) +instance Monad m => Applicative (EMT l m) where+ pure = return+ (<*>) = ap+ instance (Exception e, Throws e l, Monad m) => MonadThrow e (EMT l m) where 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+ catch = catchEMT++catchEMT :: (Exception e, Monad m) => EMT (Caught e l) m a -> (e -> EMT l m a) -> EMT l m a+catchEMT emt h = EMT $ do v <- unEMT emt case v of Right x -> return (Right x)
Control/Monad/Exception/Class.hs view
@@ -4,11 +4,16 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE OverlappingInstances #-}+ module Control.Monad.Exception.Class ( module Control.Monad, MonadThrow(..), MonadCatch(..), Throws, Caught,- WrapException(..), Exception(..), SomeException) where+ WrapException(..), Exception(..), SomeException(..),+ UncaughtException, NoExceptions, ParanoidMode+ ) where import Control.Monad import Control.Monad.Trans@@ -28,9 +33,15 @@ import Data.Monoid import Prelude hiding (catch) ++-- Closing a type class with an unexported constraint+-- @Private@ is unexported+class Private l+instance Private (Caught e l)+ {-| @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@@ -40,8 +51,7 @@ > instance Throws FileNotFoundException (Caught IOException l) -}--class Exception e => Throws e s+class (Private l, Exception e) => Throws e l -- | e -> l class Monad m => MonadThrow e m where throw :: e -> m a@@ -55,20 +65,33 @@ instance Exception e => MonadCatch e IO IO where 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)+instance Throws e l => Throws e (Caught e' l)+ -- | @SomeException@ is at the top of the exception hierarchy -- . -- Capturing SomeException captures every possible exception instance Exception e => Throws e (Caught SomeException l) +data NoExceptions+instance Private NoExceptions++data ParanoidMode+instance Private ParanoidMode++-- | Uncaught Exceptions model runtime exceptions which are not checked.+--+-- In order to declare a runtime exception it must be made an instance of @UncaughtException@+class Exception e => UncaughtException e+instance UncaughtException e => Throws e NoExceptions+ -- Labelled SomeException -- ------------------------ newtype WrapException l = WrapException {wrapException::SomeException} deriving Show- -- Throw and Catch instances for the Either and ErrorT monads -- -----------------------------------------------------------
control-monad-exception.cabal view
@@ -1,5 +1,5 @@ name: control-monad-exception-version: 0.2+version: 0.3 Cabal-Version: >= 1.2.3 build-type: Simple license: PublicDomain@@ -7,8 +7,8 @@ maintainer: pepeiborra@gmail.com homepage: http://github.com/pepeiborra/control-monad-exception description: - This package provides explicitly typed exceptions as a library.- .+ This package provides explicitly typed, checked exceptions as a library.+ /Example/ . > data Expr = Add Expr Expr | Div Expr Expr | Val Double@@ -34,6 +34,7 @@ > eval :: (Throws DivideByZero l, Throws SumOverflow l) => Expr -> EM l Double > eval `catch` \ (e::DivideByZero) -> return (-1) :: Throws SumOverflow l => Expr -> EM l Double > runEM(eval `catch` \ (e::SomeException) -> return (-1)) :: Expr -> Double+ synopsis: Explicitly typed exceptions category: Control, Monads stability: experimental@@ -53,14 +54,13 @@ base >= 3.0 && <4 else build-depends:- base >= 4.0+ base >= 4 && < 5 build-depends: transformers >= 0.0.1 && <0.2, monads-fd >= 0.0 && <0.1 extensions: MultiParamTypeClasses, FunctionalDependencies,- OverlappingInstances, FlexibleInstances, EmptyDataDecls, DeriveDataTypeable,