#if MTL
#endif
module Control.Effect.Exception (
EffectException, Exception, runException,
raise, except
) where
import Control.Effect.Bracket
import Control.Monad.Effect
#ifdef MTL
import Data.Type.Row
import qualified Control.Monad.Error.Class as E
instance (EffectBracket s l, Member (Exception s e) l, Exception s e ~ InstanceOf Exception l) => E.MonadError e (Effect l) where
throwError = raise
catchError = except
#endif
newtype Exception s e a = Exception (Tag s e -> a)
type instance Is Exception f = IsException f
type family IsException f where
IsException (Exception s e) = 'True
IsException f = 'False
class (EffectBracket s l, MemberEffect Exception (Exception s e) l) => EffectException s e l
instance (EffectBracket s l, MemberEffect Exception (Exception s e) l) => EffectException s e l
raise :: EffectException s e l => e -> Effect l a
raise e = sendEffect (Exception (\tag -> raiseWith tag e))
except :: EffectException s e l => Effect l a -> (e -> Effect l a) -> Effect l a
except x f = sendEffect (Exception (\tag -> exceptWith tag x f))
runException :: (EffectBracket s l, Show e) => Effect (Exception s e ':+ l) a -> Effect l (Either e a)
runException effect = do
tag <- newTag show
exceptWith tag
(eliminate (return . Right) (\(Exception f) k -> k (f tag)) effect)
(return . Left)