ether-0.1.0.0: src/Control/Monad/Ether/Except/Class.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | See "Control.Monad.Except".
module Control.Monad.Ether.Except.Class
( MonadExcept(..)
) where
import Data.Proxy (Proxy(Proxy))
import Control.Monad.Trans (lift)
import Control.Monad.Trans.Ether.Except hiding (throw, catch)
import qualified Control.Monad.Trans.Ether.Except as E
import qualified Control.Monad.Trans.Ether.Reader as R
import qualified Control.Monad.Trans.Ether.Writer as W
import qualified Control.Monad.Trans.Ether.State.Lazy as S.L
import qualified Control.Monad.Trans.Ether.State.Strict as S.S
import qualified Control.Ether.Util as Util
-- for mtl instances
import qualified Control.Monad.Trans.Except as Trans.E
import qualified Control.Monad.Trans.Identity as Trans.I
import qualified Control.Monad.Trans.List as Trans.L
import qualified Control.Monad.Trans.Maybe as Trans.M
import qualified Control.Monad.Trans.Reader as Trans.R
import qualified Control.Monad.Trans.State.Lazy as Trans.S.Lazy
import qualified Control.Monad.Trans.State.Strict as Trans.S.Strict
import qualified Control.Monad.Trans.Writer.Lazy as Trans.W.Lazy
import qualified Control.Monad.Trans.Writer.Strict as Trans.W.Strict
-- | See 'Control.Monad.Except.MonadError'.
class Monad m => MonadExcept tag e m | m tag -> e where
-- | Is used within a monadic computation to begin exception processing.
throw :: proxy tag -> e -> m a
-- | A handler function to handle previous exceptions and return to
-- normal execution.
catch :: proxy tag -> m a -> (e -> m a) -> m a
instance {-# OVERLAPPING #-} Monad m => MonadExcept tag e (ExceptT tag e m) where
throw = E.throw
catch = E.catch
instance MonadExcept tag e m => MonadExcept tag e (ExceptT tag' e' m) where
throw t = lift . throw t
catch t = liftCatch Proxy (catch t)
-- Instances for other tagged transformers
instance MonadExcept tag e m => MonadExcept tag e (R.ReaderT tag' r m) where
throw t = lift . throw t
catch t = R.liftCatch Proxy (catch t)
instance (Monoid w, MonadExcept tag e m) => MonadExcept tag e (W.WriterT tag' w m) where
throw t = lift . throw t
catch t = W.liftCatch Proxy (catch t)
instance MonadExcept tag e m => MonadExcept tag e (S.L.StateT tag' s m) where
throw t = lift . throw t
catch t = S.L.liftCatch Proxy (catch t)
instance MonadExcept tag e m => MonadExcept tag e (S.S.StateT tag' s m) where
throw t = lift . throw t
catch t = S.S.liftCatch Proxy (catch t)
-- Instances for mtl transformers
instance MonadExcept tag e m => MonadExcept tag e (Trans.E.ExceptT e' m) where
throw t = lift . throw t
catch t = Util.liftCatch_ExceptT (catch t)
instance MonadExcept tag e m => MonadExcept tag e (Trans.I.IdentityT m) where
throw t = lift . throw t
catch t = Trans.I.liftCatch (catch t)
instance MonadExcept tag e m => MonadExcept tag e (Trans.L.ListT m) where
throw t = lift . throw t
catch t = Trans.L.liftCatch (catch t)
instance MonadExcept tag e m => MonadExcept tag e (Trans.M.MaybeT m) where
throw t = lift . throw t
catch t = Trans.M.liftCatch (catch t)
instance MonadExcept tag e m => MonadExcept tag e (Trans.R.ReaderT r m) where
throw t = lift . throw t
catch t = Trans.R.liftCatch (catch t)
instance MonadExcept tag e m => MonadExcept tag e (Trans.S.Lazy.StateT s m) where
throw t = lift . throw t
catch t = Trans.S.Lazy.liftCatch (catch t)
instance MonadExcept tag e m => MonadExcept tag e (Trans.S.Strict.StateT s m) where
throw t = lift . throw t
catch t = Trans.S.Strict.liftCatch (catch t)
instance (Monoid w, MonadExcept tag e m) => MonadExcept tag e (Trans.W.Lazy.WriterT w m) where
throw t = lift . throw t
catch t = Trans.W.Lazy.liftCatch (catch t)
instance (Monoid w, MonadExcept tag e m) => MonadExcept tag e (Trans.W.Strict.WriterT w m) where
throw t = lift . throw t
catch t = Trans.W.Strict.liftCatch (catch t)