{-# LANGUAGE TypeOperators #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} -- | Exception-producing and exception-handling effects module Control.Eff.Exception( Exc(..) , throwExc , runExc , catchExc ) where import Data.Typeable import Control.Eff -- | These are exceptions of the type e. This is akin to the error monad. newtype Exc e v = Exc e deriving (Functor, Typeable) -- | Throw an exception in an effectful computation. throwExc :: (Typeable e, Member (Exc e) r) => e -> Eff r a throwExc e = send (\_ -> inj $ Exc e) -- | Run a computation that might produce an exception. runExc :: Typeable e => Eff (Exc e :> r) a -> Eff r (Either e a) runExc m = loop (admin m) where loop (Val x) = return (Right x) loop (E u) = handleRelay u loop (\(Exc e) -> return (Left e)) -- | Run a computation that might produce exceptions, -- and give it a way to deal with the exceptions that come up. catchExc :: (Typeable e, Member (Exc e) r) => Eff r a -> (e -> Eff r a) -> Eff r a catchExc m handle = loop (admin m) where loop (Val x) = return x loop (E u) = interpose u loop (\(Exc e) -> handle e)