module ContM (HasCont(..), runCont, ContM) where
import MT
import Monad
newtype ContM o i = C { ($$) :: (i -> o) -> o }
runCont :: ContM i i -> i
runCont m = m $$ id
instance Monad (ContM o) where
return x = C (\k -> k x)
C m >>= f = C (\k -> m (\i -> f i $$ k))
C m >> C n = C (m . const . n)
instance HasBaseMonad (ContM o) (ContM o) where
inBase = id
instance HasCont (ContM o) where
callcc f = C (\k -> f (\a -> C (\d -> k a)) $$ k)
shift :: ((a -> ContM b b) -> ContM b b) -> ContM b a
shift f = C (\k -> runCont $ f (\a -> C (\k' -> k' (k a))))
reset :: ContM a a -> ContM a a
reset m = return (runCont m)
{-
test1 = do x <- reset $ do y <- shift (\f -> do z <- f "100"
f z)
return ("10 + " ++ y)
return $ "1 + " ++ x
test2 = liftM ("1 + " ++) $ reset $ liftM ("10 + " ++) $ shift (\f -> return "100")
test3 = liftM ("1 + " ++) $ reset $ liftM ("10 + " ++) $ shift $ \f -> liftM2 (\x y -> x ++ " + " ++ y) (f "100") (f "1000")
-}