{-# LANGUAGE MultiParamTypeClasses #-} ----------------------------------------------------------------------------- -- | -- Module : Control.Monad.Trans.Conts -- Copyright : (C) 2011 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett -- Stability : provisional -- Portability : MPTCs, fundeps -- -- > Cont r ~ Contravariant.Adjoint (Op r) (Op r) -- > Conts r ~ Contravariant.AdjointT (Op r) (Op r) -- > ContsT r w m ~ Contravariant.AdjointT (Op (m r)) (Op (m r)) w ---------------------------------------------------------------------------- module Control.Monad.Trans.Conts ( -- * Continuation passing style Cont , cont , runCont -- * Multiple-continuation passing style , Conts , runConts , conts -- * Multiple-continuation passing style transformer , ContsT(..) , callCC ) where import Prelude hiding (sequence) import Control.Applicative import Control.Comonad import Control.Monad.Trans.Class import Control.Monad (ap) import Data.Functor.Apply import Data.Functor.Identity type Cont r = ContsT r Identity Identity cont :: ((a -> r) -> r) -> Cont r a cont f = ContsT $ \ (Identity k) -> Identity $ f $ runIdentity . k runCont :: Cont r a -> (a -> r) -> r runCont (ContsT k) f = runIdentity $ k $ Identity (Identity . f) type Conts r w = ContsT r w Identity conts :: Functor w => (w (a -> r) -> r) -> Conts r w a conts k = ContsT $ Identity . k . fmap (runIdentity .) runConts :: Functor w => Conts r w a -> w (a -> r) -> r runConts (ContsT k) = runIdentity . k . fmap (Identity .) newtype ContsT r w m a = ContsT { runContsT :: w (a -> m r) -> m r } instance Functor w => Functor (ContsT r w m) where fmap f (ContsT k) = ContsT $ k . fmap (. f) instance Comonad w => Apply (ContsT r w m) where (<.>) = ap instance Comonad w => Applicative (ContsT r w m) where pure x = ContsT $ \f -> extract f x (<*>) = ap instance Comonad w => Monad (ContsT r w m) where return = pure ContsT k >>= f = ContsT $ k . extend (\wa a -> runContsT (f a) wa) callCC :: Comonad w => ((a -> ContsT r w m b) -> ContsT r w m a) -> ContsT r w m a callCC f = ContsT $ \wamr -> runContsT (f (\a -> ContsT $ \_ -> extract wamr a)) wamr {- callCCs :: Comonad w => (w (a -> ContsT r w m b) -> ContsT r w m a) -> ContsT r w m a callCCs f = -} instance Comonad w => MonadTrans (ContsT r w) where lift m = ContsT $ extract . fmap (m >>=)