{-# LANGUAGE FlexibleInstances,MultiParamTypeClasses #-}
module Control.Throws where

import Control.Exception.Extensible
import Control.Monad.Identity
import Control.Monad.Reader
import Control.Monad.State

class Throws e m where
    throwException :: e -> m a

instance Exception e => Throws e Identity where
    throwException :: forall a. e -> Identity a
throwException = e -> Identity a
forall a e. Exception e => e -> a
throw

{-instance MonadError e m => Throws e m where
    throwException = throwError-}

instance Throws e (Either e) where
    throwException :: forall a. e -> Either e a
throwException = e -> Either e a
forall e a. e -> Either e a
Left

instance Exception e => Throws e IO where
    throwException :: forall a. e -> IO a
throwException = e -> IO a
forall a e. Exception e => e -> a
throw

instance Throws e m => Throws e (StateT s m) where
    throwException :: forall a. e -> StateT s m a
throwException e
x = (s -> m (a, s)) -> StateT s m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT (\s
s -> e -> m (a, s)
forall a. e -> m a
forall e (m :: * -> *) a. Throws e m => e -> m a
throwException e
x)

instance Throws e m => Throws e (ReaderT s m) where
    throwException :: forall a. e -> ReaderT s m a
throwException e
x = (s -> m a) -> ReaderT s m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT (\s
s -> e -> m a
forall a. e -> m a
forall e (m :: * -> *) a. Throws e m => e -> m a
throwException e
x)