cps-except-0.0.1.0: src/Control/Monad/CPSExcept.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Monad.CPSExcept where
import Control.Monad.Except
import Control.Monad.State
import Control.Monad.Reader()
import Control.Monad.Writer()
import Control.Monad.RWS()
newtype CPSExceptT e m a =
CPSExceptT { getCPSExceptT :: forall r. ((e -> m r) -> (a -> m r) -> m r) }
runCPSExceptT :: Applicative m => CPSExceptT e m a -> m (Either e a)
runCPSExceptT (CPSExceptT f) = f (pure . Left) (pure . Right)
{-# INLINE runCPSExceptT #-}
instance Functor (CPSExceptT e m) where
fmap f (CPSExceptT g) = CPSExceptT $ \failC successC ->
g failC (successC . f)
{-# INLINE fmap #-}
instance Monad m => Applicative (CPSExceptT e m) where
pure x = CPSExceptT $ \_failC successC -> successC x
{-# INLINE pure #-}
(<*>) = ap
{-# INLINE (<*>) #-}
instance Monad m => Monad (CPSExceptT e m) where
CPSExceptT f >>= g = CPSExceptT $ \failC successC ->
f failC (\a -> getCPSExceptT (g a) failC successC)
{-# INLINE (>>=) #-}
instance Monad m => MonadError e (CPSExceptT e m) where
throwError e = CPSExceptT $ \failC _successC -> failC e
{-# INLINE throwError #-}
catchError (CPSExceptT f) handler =
CPSExceptT $ \failC successC ->
f (\e -> getCPSExceptT (handler e) failC successC)
successC
{-# INLINE catchError #-}
instance MonadTrans (CPSExceptT e) where
lift m = CPSExceptT $ \_failC successC -> m >>= successC
{-# INLINE lift #-}
instance MonadState s m => MonadState s (CPSExceptT e m) where
state f = lift $ state f
{-# INLINE state #-}