module Control.Monad.Failure where
import Control.Exception (throw, Exception)
import Control.Monad
#if TRANSFORMERS
import Control.Monad.Trans
import Control.Monad.Trans.Error
import Control.Monad.Trans.List
import Control.Monad.Trans.Reader
import Control.Monad.Trans.State
import Control.Monad.Trans.Writer
import Control.Monad.Trans.RWS
#else
import Control.Monad.Error
import Control.Monad.List
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.RWS
#endif
import Data.Monoid
class Monad m => MonadFailure e m where
failure :: e -> m a
instance MonadFailure e Maybe where failure _ = Nothing
instance MonadFailure e [] where failure _ = []
instance Exception e => MonadFailure e IO where
failure = Control.Exception.throw
instance (Error e) => MonadFailure e (Either e) where
failure = Left
instance (Error e, Monad m) => MonadFailure e (ErrorT e m) where
failure = throwError
instance MonadFailure e m => MonadFailure e (ListT m) where
failure = lift . failure
instance MonadFailure e m => MonadFailure e (ReaderT r m) where
failure = lift . failure
instance (Monoid w, MonadFailure e m) => MonadFailure e (WriterT w m) where
failure = lift . failure
instance MonadFailure e m => MonadFailure e (StateT s m) where
failure = lift . failure
instance (Monoid w, MonadFailure e m) => MonadFailure e (RWST r w s m) where
failure = lift . failure