{-# LANGUAGE CPP #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

-- | Monad type classes for raising errors and recovering from them.
module Control.Monad.Abort.Class
  ( MonadAbort(..)
  , MonadRecover(..)
  , onError
  , onError_
  , ignoreErrors
  ) where

#if !MIN_VERSION_base(4,6,0)
import Prelude hiding (catch)
#endif
import Data.Monoid (Monoid)
import Control.Exception (SomeException, throwIO, catch)
import Control.Applicative (Applicative, (<$>))
import Control.Monad.Trans.Identity
import Control.Monad.Trans.Maybe
import Control.Monad.Cont
#if !MIN_VERSION_mtl(2,3,0)
import Control.Monad.List
import Control.Monad.Error
#else
import Control.Monad.Error.Class
#endif
import Control.Monad.Trans.Except
import Control.Monad.Reader
import Control.Monad.State (MonadState(..))
import qualified Control.Monad.State.Lazy as L
import qualified Control.Monad.State.Strict as S
import Control.Monad.Writer (MonadWriter(..))
import qualified Control.Monad.Writer.Lazy as L
import qualified Control.Monad.Writer.Strict as S
import Control.Monad.RWS (MonadRWS)
import qualified Control.Monad.RWS.Lazy as L
import qualified Control.Monad.RWS.Strict as S
import Control.Monad.Trans.Accum (AccumT(..), runAccumT)
import Control.Monad.Trans.Select (SelectT(..))
import Control.Monad.Trans.Abort (AbortT(..))
import qualified Control.Monad.Trans.Abort as A
import Control.Monad.Trans.Finish (FinishT(..))
import Control.Monad.STM (STM, throwSTM, catchSTM)

-- | Class of monads that support raising of errors.
class (Applicative μ, Monad μ)  MonadAbort e μ | μ  e where
  -- | Raise an error.
  --
  -- @
  --     'abort' e >>= rest = 'abort' e
  -- @
  abort  e  μ α

-- | Class of monads that support recovery from errors.
class MonadAbort e μ  MonadRecover e μ | μ  e where
#if __GLASGOW_HASKELL__ >= 708
  {-# MINIMAL recover | evaluate #-}
#endif
  -- | @'recover' m h@ recovers from errors raised in computation @m@ using
  -- the provided error handler @h@. The default implementation is
  --
  -- @
  --   'evaluate' m '>>=' 'either' h 'return'
  -- @
  recover  μ α  (e  μ α)  μ α
  recover μ α
m e -> μ α
h = forall e (μ :: * -> *) α. MonadRecover e μ => μ α -> μ (Either e α)
evaluate μ α
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either e -> μ α
h forall (m :: * -> *) a. Monad m => a -> m a
return
  -- | @'evaluate' m@ runs computation @m@, returning @'Left' e@ if it
  -- raised an error @e@. The default implementation is
  --
  -- @
  --    'recover' ('Right' '<$>' m) ('return' . 'Left')
  -- @
  evaluate  μ α  μ (Either e α)
  evaluate μ α
m = forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
recover (forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> μ α
m) (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left)

-- | Run an action on error, without recovering from it.
onError  MonadRecover e μ  μ α  (e  μ β)  μ α
onError :: forall e (μ :: * -> *) α β.
MonadRecover e μ =>
μ α -> (e -> μ β) -> μ α
onError μ α
m e -> μ β
h = forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
recover μ α
m (\e
e  e -> μ β
h e
e forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort e
e)

-- | Run an action on error (ignoring the error value), without recovering
-- from it.
onError_  MonadRecover e μ  μ α  μ β  μ α
onError_ :: forall e (μ :: * -> *) α β. MonadRecover e μ => μ α -> μ β -> μ α
onError_ μ α
m = forall e (μ :: * -> *) α β.
MonadRecover e μ =>
μ α -> (e -> μ β) -> μ α
onError μ α
m forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const

-- | Silently recover from all errors.
ignoreErrors  MonadRecover e μ  μ α  μ ()
ignoreErrors :: forall e (μ :: * -> *) α. MonadRecover e μ => μ α -> μ ()
ignoreErrors μ α
m = forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
recover (μ α
m forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()) (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ())

instance (Functor μ, Monad μ)  MonadAbort e (AbortT e μ) where
  abort :: forall α. e -> AbortT e μ α
abort = forall (μ :: * -> *) e α. Monad μ => e -> AbortT e μ α
A.abort

instance (Functor μ, Monad μ)  MonadRecover e (AbortT e μ) where
  recover :: forall α. AbortT e μ α -> (e -> AbortT e μ α) -> AbortT e μ α
recover = forall (μ :: * -> *) e α.
Monad μ =>
AbortT e μ α -> (e -> AbortT e μ α) -> AbortT e μ α
A.recover

instance MonadAbort SomeException IO where
  abort :: forall α. SomeException -> IO α
abort = forall e a. Exception e => e -> IO a
throwIO

instance MonadRecover SomeException IO where
  recover :: forall α. IO α -> (SomeException -> IO α) -> IO α
recover = forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch

instance MonadAbort SomeException STM where
  abort :: forall α. SomeException -> STM α
abort = forall e a. Exception e => e -> STM a
throwSTM

instance MonadRecover SomeException STM where
  recover :: forall α. STM α -> (SomeException -> STM α) -> STM α
recover = forall e a. Exception e => STM a -> (e -> STM a) -> STM a
catchSTM

instance Monad μ  MonadError e (AbortT e μ) where
  throwError :: forall a. e -> AbortT e μ a
throwError = forall (μ :: * -> *) e α. Monad μ => e -> AbortT e μ α
A.abort
  catchError :: forall a. AbortT e μ a -> (e -> AbortT e μ a) -> AbortT e μ a
catchError = forall (μ :: * -> *) e α.
Monad μ =>
AbortT e μ α -> (e -> AbortT e μ α) -> AbortT e μ α
A.recover

instance MonadCont μ  MonadCont (AbortT e μ) where
  callCC :: forall a b. ((a -> AbortT e μ b) -> AbortT e μ a) -> AbortT e μ a
callCC (a -> AbortT e μ b) -> AbortT e μ a
k = forall e (μ :: * -> *) α. μ (Either e α) -> AbortT e μ α
AbortT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b. MonadCont m => ((a -> m b) -> m a) -> m a
callCC forall a b. (a -> b) -> a -> b
$ \Either e a -> μ b
f  forall e (μ :: * -> *) α. AbortT e μ α -> μ (Either e α)
runAbortT forall a b. (a -> b) -> a -> b
$ (a -> AbortT e μ b) -> AbortT e μ a
k (forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either e a -> μ b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right) 

instance MonadReader r μ  MonadReader r (AbortT e μ) where
  ask :: AbortT e μ r
ask = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall r (m :: * -> *). MonadReader r m => m r
ask
  local :: forall a. (r -> r) -> AbortT e μ a -> AbortT e μ a
local r -> r
f = forall e (μ :: * -> *) α. μ (Either e α) -> AbortT e μ α
AbortT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. AbortT e μ α -> μ (Either e α)
runAbortT

instance MonadState s μ  MonadState s (AbortT e μ) where
  get :: AbortT e μ s
get = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall s (m :: * -> *). MonadState s m => m s
get
  put :: s -> AbortT e μ ()
put = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *). MonadState s m => s -> m ()
put

instance MonadWriter w μ  MonadWriter w (AbortT e μ) where
  tell :: w -> AbortT e μ ()
tell = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell
  listen :: forall a. AbortT e μ a -> AbortT e μ (a, w)
listen AbortT e μ a
m = forall e (μ :: * -> *) α. μ (Either e α) -> AbortT e μ α
AbortT forall a b. (a -> b) -> a -> b
$ do
    (Either e a
lr, w
w)  forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen forall a b. (a -> b) -> a -> b
$ forall e (μ :: * -> *) α. AbortT e μ α -> μ (Either e α)
runAbortT AbortT e μ a
m
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (, w
w) Either e a
lr
  pass :: forall a. AbortT e μ (a, w -> w) -> AbortT e μ a
pass AbortT e μ (a, w -> w)
m = forall e (μ :: * -> *) α. μ (Either e α) -> AbortT e μ α
AbortT forall a b. (a -> b) -> a -> b
$ forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass forall a b. (a -> b) -> a -> b
$ do
    Either e (a, w -> w)
lr  forall e (μ :: * -> *) α. AbortT e μ α -> μ (Either e α)
runAbortT AbortT e μ (a, w -> w)
m
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((, forall a. a -> a
id) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left) (\(a
r, w -> w
f)  (forall a b. b -> Either a b
Right a
r, w -> w
f)) Either e (a, w -> w)
lr

instance MonadRWS r w s μ  MonadRWS r w s (AbortT e μ)

instance MonadAbort e μ  MonadAbort e (IdentityT μ) where
  abort :: forall α. e -> IdentityT μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (IdentityT μ) where
  recover :: forall α. IdentityT μ α -> (e -> IdentityT μ α) -> IdentityT μ α
recover IdentityT μ α
m e -> IdentityT μ α
h = forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT forall a b. (a -> b) -> a -> b
$ forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT IdentityT μ α
m forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> IdentityT μ α
h)

instance MonadAbort e μ  MonadAbort e (ContT r μ) where
  abort :: forall α. e -> ContT r μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadAbort e μ  MonadAbort e (MaybeT μ) where
  abort :: forall α. e -> MaybeT μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (MaybeT μ) where
  recover :: forall α. MaybeT μ α -> (e -> MaybeT μ α) -> MaybeT μ α
recover MaybeT μ α
m e -> MaybeT μ α
h = forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT MaybeT μ α
m forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> MaybeT μ α
h)

#if !MIN_VERSION_mtl(2,3,0)
instance MonadAbort e μ  MonadAbort e (ListT μ) where
  abort :: forall α. e -> ListT μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (ListT μ) where
  recover :: forall α. ListT μ α -> (e -> ListT μ α) -> ListT μ α
recover ListT μ α
m e -> ListT μ α
h = forall (m :: * -> *) a. m [a] -> ListT m a
ListT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ListT m a -> m [a]
runListT ListT μ α
m forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (forall (m :: * -> *) a. ListT m a -> m [a]
runListT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> ListT μ α
h)
#endif

instance MonadAbort e μ  MonadAbort e (ReaderT r μ) where
  abort :: forall α. e -> ReaderT r μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (ReaderT r μ) where
  recover :: forall α. ReaderT r μ α -> (e -> ReaderT r μ α) -> ReaderT r μ α
recover ReaderT r μ α
m e -> ReaderT r μ α
h = forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ \r
r  forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r μ α
m r
r forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` ((forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`runReaderT` r
r) forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> ReaderT r μ α
h)

instance MonadAbort e μ  MonadAbort e (L.StateT s μ) where
  abort :: forall α. e -> StateT s μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (L.StateT s μ) where
  recover :: forall α. StateT s μ α -> (e -> StateT s μ α) -> StateT s μ α
recover StateT s μ α
m e -> StateT s μ α
h = forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
L.StateT forall a b. (a -> b) -> a -> b
$ \s
s 
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
L.runStateT StateT s μ α
m s
s forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` ((forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
`L.runStateT` s
s) forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> StateT s μ α
h)

instance MonadAbort e μ  MonadAbort e (S.StateT s μ) where
  abort :: forall α. e -> StateT s μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (S.StateT s μ) where
  recover :: forall α. StateT s μ α -> (e -> StateT s μ α) -> StateT s μ α
recover StateT s μ α
m e -> StateT s μ α
h = forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
S.StateT forall a b. (a -> b) -> a -> b
$ \s
s 
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
S.runStateT StateT s μ α
m s
s forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` ((forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
`S.runStateT` s
s) forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> StateT s μ α
h)

instance (MonadAbort e μ, Monoid w)  MonadAbort e (L.WriterT w μ) where
  abort :: forall α. e -> WriterT w μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance (MonadRecover e μ, Monoid w)  MonadRecover e (L.WriterT w μ) where
  recover :: forall α. WriterT w μ α -> (e -> WriterT w μ α) -> WriterT w μ α
recover WriterT w μ α
m e -> WriterT w μ α
h = forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
L.WriterT forall a b. (a -> b) -> a -> b
$ forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT WriterT w μ α
m forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> WriterT w μ α
h)

instance (MonadAbort e μ, Monoid w)  MonadAbort e (S.WriterT w μ) where
  abort :: forall α. e -> WriterT w μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance (MonadRecover e μ, Monoid w)  MonadRecover e (S.WriterT w μ) where
  recover :: forall α. WriterT w μ α -> (e -> WriterT w μ α) -> WriterT w μ α
recover WriterT w μ α
m e -> WriterT w μ α
h = forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
S.WriterT forall a b. (a -> b) -> a -> b
$ forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
S.runWriterT WriterT w μ α
m forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
S.runWriterT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> WriterT w μ α
h)

instance (MonadAbort e μ, Monoid w)  MonadAbort e (L.RWST r w s μ) where
  abort :: forall α. e -> RWST r w s μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance (MonadRecover e μ, Monoid w)  MonadRecover e (L.RWST r w s μ) where
  recover :: forall α. RWST r w s μ α -> (e -> RWST r w s μ α) -> RWST r w s μ α
recover RWST r w s μ α
m e -> RWST r w s μ α
h = forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
L.RWST forall a b. (a -> b) -> a -> b
$ \r
r s
s 
    forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST RWST r w s μ α
m r
r s
s forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (\e
e  forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST (e -> RWST r w s μ α
h e
e) r
r s
s)

instance (MonadAbort e μ, Monoid w)  MonadAbort e (S.RWST r w s μ) where
  abort :: forall α. e -> RWST r w s μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance (MonadRecover e μ, Monoid w)  MonadRecover e (S.RWST r w s μ) where
  recover :: forall α. RWST r w s μ α -> (e -> RWST r w s μ α) -> RWST r w s μ α
recover RWST r w s μ α
m e -> RWST r w s μ α
h = forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
S.RWST forall a b. (a -> b) -> a -> b
$ \r
r s
s 
    forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
S.runRWST RWST r w s μ α
m r
r s
s forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` (\e
e  forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
S.runRWST (e -> RWST r w s μ α
h e
e) r
r s
s)

#if !MIN_VERSION_mtl(2,3,0)
instance (Functor μ, Monad μ, Error e)  MonadAbort e (ErrorT e μ) where
  abort :: forall α. e -> ErrorT e μ α
abort = forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError

instance (Functor μ, Monad μ, Error e)  MonadRecover e (ErrorT e μ) where
  recover :: forall α. ErrorT e μ α -> (e -> ErrorT e μ α) -> ErrorT e μ α
recover = forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
#endif

instance (Functor μ, Monad μ)  MonadAbort e (ExceptT e μ) where
  abort :: forall α. e -> ExceptT e μ α
abort = forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError

instance (Functor μ, Monad μ)  MonadRecover e (ExceptT e μ) where
  recover :: forall α. ExceptT e μ α -> (e -> ExceptT e μ α) -> ExceptT e μ α
recover = forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError

instance (Monoid w, MonadAbort e μ)  MonadAbort e (AccumT w μ) where
  abort :: forall α. e -> AccumT w μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance (Monoid w, MonadRecover e μ)  MonadRecover e (AccumT w μ) where
  recover :: forall α. AccumT w μ α -> (e -> AccumT w μ α) -> AccumT w μ α
recover AccumT w μ α
m e -> AccumT w μ α
h = forall w (m :: * -> *) a. (w -> m (a, w)) -> AccumT w m a
AccumT forall a b. (a -> b) -> a -> b
$ \w
w  forall w (m :: * -> *) a. AccumT w m a -> w -> m (a, w)
runAccumT AccumT w μ α
m w
w forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
`recover` ((forall w (m :: * -> *) a. AccumT w m a -> w -> m (a, w)
`runAccumT` w
w) forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> AccumT w μ α
h)

instance MonadAbort e μ  MonadAbort e (SelectT r μ) where
  abort :: forall α. e -> SelectT r μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadAbort e μ  MonadAbort e (FinishT f μ) where
  abort :: forall α. e -> FinishT f μ α
abort = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (μ :: * -> *) α. MonadAbort e μ => e -> μ α
abort

instance MonadRecover e μ  MonadRecover e (FinishT f μ) where
  recover :: forall α. FinishT f μ α -> (e -> FinishT f μ α) -> FinishT f μ α
recover FinishT f μ α
m e -> FinishT f μ α
h = forall f (μ :: * -> *) α. μ (Either f α) -> FinishT f μ α
FinishT forall a b. (a -> b) -> a -> b
$ forall e (μ :: * -> *) α.
MonadRecover e μ =>
μ α -> (e -> μ α) -> μ α
recover (forall f (μ :: * -> *) α. FinishT f μ α -> μ (Either f α)
runFinishT FinishT f μ α
m) (forall f (μ :: * -> *) α. FinishT f μ α -> μ (Either f α)
runFinishT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> FinishT f μ α
h)