    {-# 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. (HasCallStack, 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. (HasCallStack, 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)