{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE Safe #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
module Control.Monad.Error.Class (
MonadError(..),
liftEither,
tryError,
withError,
handleError,
mapError,
) where
import Control.Monad.Trans.Except (ExceptT)
import qualified Control.Monad.Trans.Except as ExceptT (throwE, catchE)
import Control.Monad.Trans.Identity (IdentityT)
import qualified Control.Monad.Trans.Identity as Identity
import Control.Monad.Trans.Maybe (MaybeT)
import qualified Control.Monad.Trans.Maybe as Maybe
import Control.Monad.Trans.Reader (ReaderT)
import qualified Control.Monad.Trans.Reader as Reader
import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS
import qualified Control.Monad.Trans.RWS.Strict as StrictRWS
import qualified Control.Monad.Trans.State.Lazy as LazyState
import qualified Control.Monad.Trans.State.Strict as StrictState
import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter
import qualified Control.Monad.Trans.Writer.Strict as StrictWriter
import Control.Monad.Trans.Accum (AccumT)
import qualified Control.Monad.Trans.Accum as Accum
import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
import qualified Control.Monad.Trans.Writer.CPS as CPSWriter
import Control.Monad.Trans.Class (lift)
import Control.Exception (IOException, catch, ioError)
import Control.Monad (Monad)
import Data.Monoid (Monoid)
import Prelude (Either (Left, Right), Maybe (Nothing), either, flip, (.), IO, pure, (<$>), (>>=))
class (Monad m) => MonadError e m | m -> e where
throwError :: e -> m a
catchError :: m a -> (e -> m a) -> m a
{-# MINIMAL throwError, catchError #-}
liftEither :: MonadError e m => Either e a -> m a
liftEither :: Either e a -> m a
liftEither = (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
instance MonadError IOException IO where
throwError :: IOException -> IO a
throwError = IOException -> IO a
forall a. IOException -> IO a
ioError
catchError :: IO a -> (IOException -> IO a) -> IO a
catchError = IO a -> (IOException -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch
instance MonadError () Maybe where
throwError :: () -> Maybe a
throwError () = Maybe a
forall a. Maybe a
Nothing
catchError :: Maybe a -> (() -> Maybe a) -> Maybe a
catchError Maybe a
Nothing () -> Maybe a
f = () -> Maybe a
f ()
catchError Maybe a
x () -> Maybe a
_ = Maybe a
x
instance MonadError e (Either e) where
throwError :: e -> Either e a
throwError = e -> Either e a
forall e a. e -> Either e a
Left
Left e
l catchError :: Either e a -> (e -> Either e a) -> Either e a
`catchError` e -> Either e a
h = e -> Either e a
h e
l
Right a
r `catchError` e -> Either e a
_ = a -> Either e a
forall a b. b -> Either a b
Right a
r
instance Monad m => MonadError e (ExceptT e m) where
throwError :: e -> ExceptT e m a
throwError = e -> ExceptT e m a
forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
ExceptT.throwE
catchError :: ExceptT e m a -> (e -> ExceptT e m a) -> ExceptT e m a
catchError = ExceptT e m a -> (e -> ExceptT e m a) -> ExceptT e m a
forall (m :: * -> *) e a e'.
Monad m =>
ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a
ExceptT.catchE
instance MonadError e m => MonadError e (IdentityT m) where
throwError :: e -> IdentityT m a
throwError = m a -> IdentityT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> IdentityT m a) -> (e -> m a) -> e -> IdentityT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: IdentityT m a -> (e -> IdentityT m a) -> IdentityT m a
catchError = Catch e m a
-> IdentityT m a -> (e -> IdentityT m a) -> IdentityT m a
forall k e (m :: k -> *) (a :: k).
Catch e m a -> Catch e (IdentityT m) a
Identity.liftCatch Catch e m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance MonadError e m => MonadError e (MaybeT m) where
throwError :: e -> MaybeT m a
throwError = m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> MaybeT m a) -> (e -> m a) -> e -> MaybeT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: MaybeT m a -> (e -> MaybeT m a) -> MaybeT m a
catchError = Catch e m (Maybe a)
-> MaybeT m a -> (e -> MaybeT m a) -> MaybeT m a
forall e (m :: * -> *) a.
Catch e m (Maybe a) -> Catch e (MaybeT m) a
Maybe.liftCatch Catch e m (Maybe a)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance MonadError e m => MonadError e (ReaderT r m) where
throwError :: e -> ReaderT r m a
throwError = m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT r m a) -> (e -> m a) -> e -> ReaderT r m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: ReaderT r m a -> (e -> ReaderT r m a) -> ReaderT r m a
catchError = Catch e m a
-> ReaderT r m a -> (e -> ReaderT r m a) -> ReaderT r m a
forall e (m :: * -> *) a r. Catch e m a -> Catch e (ReaderT r m) a
Reader.liftCatch Catch e m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance (Monoid w, MonadError e m) => MonadError e (LazyRWS.RWST r w s m) where
throwError :: e -> RWST r w s m a
throwError = m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> RWST r w s m a) -> (e -> m a) -> e -> RWST r w s m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a
catchError = Catch e m (a, s, w)
-> RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a
forall e (m :: * -> *) a s w r.
Catch e m (a, s, w) -> Catch e (RWST r w s m) a
LazyRWS.liftCatch Catch e m (a, s, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance (Monoid w, MonadError e m) => MonadError e (StrictRWS.RWST r w s m) where
throwError :: e -> RWST r w s m a
throwError = m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> RWST r w s m a) -> (e -> m a) -> e -> RWST r w s m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a
catchError = Catch e m (a, s, w)
-> RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a
forall e (m :: * -> *) a s w r.
Catch e m (a, s, w) -> Catch e (RWST r w s m) a
StrictRWS.liftCatch Catch e m (a, s, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance MonadError e m => MonadError e (LazyState.StateT s m) where
throwError :: e -> StateT s m a
throwError = m a -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> StateT s m a) -> (e -> m a) -> e -> StateT s m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: StateT s m a -> (e -> StateT s m a) -> StateT s m a
catchError = Catch e m (a, s)
-> StateT s m a -> (e -> StateT s m a) -> StateT s m a
forall e (m :: * -> *) a s.
Catch e m (a, s) -> Catch e (StateT s m) a
LazyState.liftCatch Catch e m (a, s)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance MonadError e m => MonadError e (StrictState.StateT s m) where
throwError :: e -> StateT s m a
throwError = m a -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> StateT s m a) -> (e -> m a) -> e -> StateT s m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: StateT s m a -> (e -> StateT s m a) -> StateT s m a
catchError = Catch e m (a, s)
-> StateT s m a -> (e -> StateT s m a) -> StateT s m a
forall e (m :: * -> *) a s.
Catch e m (a, s) -> Catch e (StateT s m) a
StrictState.liftCatch Catch e m (a, s)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance (Monoid w, MonadError e m) => MonadError e (LazyWriter.WriterT w m) where
throwError :: e -> WriterT w m a
throwError = m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> WriterT w m a) -> (e -> m a) -> e -> WriterT w m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
catchError = Catch e m (a, w)
-> WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
forall e (m :: * -> *) a w.
Catch e m (a, w) -> Catch e (WriterT w m) a
LazyWriter.liftCatch Catch e m (a, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance (Monoid w, MonadError e m) => MonadError e (StrictWriter.WriterT w m) where
throwError :: e -> WriterT w m a
throwError = m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> WriterT w m a) -> (e -> m a) -> e -> WriterT w m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
catchError = Catch e m (a, w)
-> WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
forall e (m :: * -> *) a w.
Catch e m (a, w) -> Catch e (WriterT w m) a
StrictWriter.liftCatch Catch e m (a, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance (Monoid w, MonadError e m) => MonadError e (CPSRWS.RWST r w s m) where
throwError :: e -> RWST r w s m a
throwError = m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> RWST r w s m a) -> (e -> m a) -> e -> RWST r w s m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a
catchError = Catch e m (a, s, w)
-> RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a
forall e (m :: * -> *) a s w r.
Catch e m (a, s, w) -> Catch e (RWST r w s m) a
CPSRWS.liftCatch Catch e m (a, s, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance (Monoid w, MonadError e m) => MonadError e (CPSWriter.WriterT w m) where
throwError :: e -> WriterT w m a
throwError = m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> WriterT w m a) -> (e -> m a) -> e -> WriterT w m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
catchError = Catch e m (a, w)
-> WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
forall e (m :: * -> *) a w.
Catch e m (a, w) -> Catch e (WriterT w m) a
CPSWriter.liftCatch Catch e m (a, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
instance
( Monoid w
, MonadError e m
) => MonadError e (AccumT w m) where
throwError :: e -> AccumT w m a
throwError = m a -> AccumT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> AccumT w m a) -> (e -> m a) -> e -> AccumT w m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: AccumT w m a -> (e -> AccumT w m a) -> AccumT w m a
catchError = Catch e m (a, w)
-> AccumT w m a -> (e -> AccumT w m a) -> AccumT w m a
forall e (m :: * -> *) a w.
Catch e m (a, w) -> Catch e (AccumT w m) a
Accum.liftCatch Catch e m (a, w)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
tryError :: MonadError e m => m a -> m (Either e a)
tryError :: m a -> m (Either e a)
tryError m a
action = (a -> Either e a
forall a b. b -> Either a b
Right (a -> Either e a) -> m a -> m (Either e a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
action) m (Either e a) -> (e -> m (Either e a)) -> m (Either e a)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
`catchError` (Either e a -> m (Either e a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either e a -> m (Either e a))
-> (e -> Either e a) -> e -> m (Either e a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Either e a
forall e a. e -> Either e a
Left)
withError :: MonadError e m => (e -> e) -> m a -> m a
withError :: (e -> e) -> m a -> m a
withError e -> e
f m a
action = m a -> m (Either e a)
forall e (m :: * -> *) a. MonadError e m => m a -> m (Either e a)
tryError m a
action m (Either e a) -> (Either e a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (e -> m a) -> (e -> e) -> e -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> e
f) a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
handleError :: MonadError e m => (e -> m a) -> m a -> m a
handleError :: (e -> m a) -> m a -> m a
handleError = (m a -> (e -> m a) -> m a) -> (e -> m a) -> m a -> m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip m a -> (e -> m a) -> m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
mapError :: (MonadError e m, MonadError e' n) => (m (Either e a) -> n (Either e' b)) -> m a -> n b
mapError :: (m (Either e a) -> n (Either e' b)) -> m a -> n b
mapError m (Either e a) -> n (Either e' b)
f m a
action = m (Either e a) -> n (Either e' b)
f (m a -> m (Either e a)
forall e (m :: * -> *) a. MonadError e m => m a -> m (Either e a)
tryError m a
action) n (Either e' b) -> (Either e' b -> n b) -> n b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either e' b -> n b
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither