{-# OPTIONS -XNoMonomorphismRestriction #-} module Main where import Control.Monad import Control.Monad.Cont import Control.Monad.State import Control.Monad.Identity data (Monad m) => RecPair m a b r = Nil r | RP (b, a -> m (RecPair m a b r)) yield :: (Monad m) => r -> ContT (RecPair m a r v) m a yield x = ContT $ \k -> return $ RP(x, k) f'cps = return 2 test = do x <- f'cps yield x yield (x + 1) return (-1) testSt = do y <- f'cps v <- get put (y + v) yield v testSt getRP :: RecPair Identity a a a -> [a] getRP (Nil x) = [x] getRP (RP (b, f)) = b : (getRP $ runIdentity $ f b) runYield :: ContT (RecPair m a1 b a) Identity a -> RecPair m a1 b a runYield f = runIdentity $ runContT f (\x -> return $ Nil x) --result is [2,3, -1] runTest = getRP $ runYield test getRPSt :: (RecPair (State t) v v v, t) -> [v] getRPSt (Nil x, _) = [x] getRPSt (RP (b, f), s) = b : (getRPSt $ runState (f b) s) runYieldSt :: ContT (RecPair m a1 b a) (State s) a -> s -> (RecPair m a1 b a, s) runYieldSt f iState = runState (runContT f (\x -> return $ Nil x)) iState --result is [iState, iState + 2..] runTestSt iState = getRPSt $ runYieldSt testSt iState