[Haskell-cafe] Control.Monad.Cont fun
Tomasz Zielonka
tomasz.zielonka at gmail.com
Thu Jul 7 13:08:23 EDT 2005
Hello!
Some time ago I wanted to return the escape continuation out of the
callCC block, like this:
getCC = callCC (\c -> return c)
But of course this wouldn't compile.
I thought that it would be useful to be able to keep the current
continuation and resume it later, like you can in do in scheme. Well,
it was easy to do this in Haskell in the (ContT r IO) monad, by using an
IORef. But I wasn't able to solve this for all MonadCont monads.
After more then year of on-and-off trials, I've finally managed to do
this! ;-)
import Control.Monad.Cont
getCC :: MonadCont m => m (m a)
getCC = callCC (\c -> let x = c x in return x)
getCC' :: MonadCont m => a -> m (a, a -> m b)
getCC' x0 = callCC (\c -> let f x = c (x, f) in return (x0, f))
getCC allows to set a backward "goto label". Here's an example:
-- prints "hello!" in an endless loop
test :: IO ()
test = (`runContT` return) $ do
jump <- getCC
lift (putStrLn "hello!")
jump
getCC' allows to jump back with arguments:
-- prints integers from 0 to 10, then prints finish and ends
test' :: IO ()
test' = (`runContT` return) $ do
(x, jumpWith) <- getCC' 0
lift (print x)
when (x < 10) (jumpWith (x + 1))
lift (putStrLn "finish")
I think this is rather cool! :-)
Besides sharing my happiness, I want to ask some questions:
- what would be the best names for these functions
- is it possible to define a MonadFix instance for Cont / ContT?
- do you think it would be a good idea to add them to
Control.Monad.Cont?
Best regards
Tomasz
More information about the Haskell-Cafe
mailing list