hs-functors-0.1.3.0: Control/Monad/Codensity.hs
{-# LANGUAGE RankNTypes #-}
module Control.Monad.Codensity where
import Prelude hiding (fail)
import Control.Applicative
import Control.Monad hiding (fail)
import Control.Monad.Fail
import Control.Monad.Trans.Class
newtype Codensity m a = Codensity { codensity :: ∀ b . (a -> m b) -> m b }
deriving instance Functor (Codensity m)
instance Applicative (Codensity p) where
pure x = Codensity ($ x)
Codensity x <*> Codensity y = Codensity (\ g -> x (\ f -> y (g . f)))
instance Monad (Codensity m) where
Codensity x >>= f = Codensity (x . flip (codensity . f))
instance MonadFail f => MonadFail (Codensity f) where
fail xs = Codensity (\ _ -> fail xs)
instance Alternative p => Alternative (Codensity p) where
empty = Codensity (pure empty)
Codensity x <|> Codensity y = Codensity (liftA2 (<|>) x y)
instance Alternative p => MonadPlus (Codensity p)
instance MonadTrans Codensity where lift xm = Codensity (xm >>=)
unlift :: Applicative p => Codensity p a -> p a
unlift = flip codensity pure