module Control.Monad.Trans.Cont.Comonadic where
import Control.Comonad
import Control.Applicative
import Control.Monad (ap)
import Data.Functor.Apply
import Data.Functor.Identity
type Cont r = ContW r Identity
cont :: ((a -> r) -> r) -> Cont r a
cont f = ContW (f . runIdentity)
runCont :: Cont r a -> (a -> r) -> r
runCont (ContW k) = k . Identity
newtype ContW r w a = ContW { runContW :: w (a -> r) -> r }
instance Functor w => Functor (ContW r w) where
fmap f (ContW k) = ContW $ k . fmap (. f)
instance Comonad w => FunctorApply (ContW r w) where
(<.>) = ap
instance Comonad w => Applicative (ContW r w) where
pure x = ContW $ \wk -> extract wk x
(<*>) = ap
instance Comonad w => Monad (ContW r w) where
return = pure
ContW k >>= f = ContW $ k . extend (\wa a -> runContW (f a) wa)
callCC :: Comonad w => ((a -> ContW r w b) -> ContW r w a) -> ContW r w a
callCC f = ContW $ \wc -> runContW (f (\a -> ContW $ \_ -> extract wc a)) wc