module Control.Monad.Ran.Codensity ( Codensity(Codensity, getCodensity) , runCodensity, runCodensityApp ) where import Control.Monad import Control.Monad.Trans import Control.Monad.Ran import Control.Applicative newtype Codensity f a = Codensity { getCodensity :: forall o. (a -> f o) -> f o } instance Functor (Codensity f) where fmap f (Codensity g) = Codensity (\k -> g (\a -> k (f a))) instance Applicative (Codensity f) where pure = return (<*>) = ap instance Monad (Codensity f) where return a = Codensity (\k -> k a) Codensity g >>= f = Codensity (\k -> g (\a -> getCodensity (f a) k)) runCodensity :: Monad f => Codensity f a -> f a runCodensity (Codensity f) = f return runCodensityApp :: Applicative f => Codensity f a -> f a runCodensityApp (Codensity f) = f pure instance MonadTrans Codensity where lift m = Codensity (m >>=) instance RanIso f f (Codensity f) where toRan x = Ran (getCodensity x) fromRan x = Codensity (getRan x)