Monadic Call/CC?

Ashley Yakeley ashley@semantic.org
Fri, 22 Feb 2002 19:03:48 -0800


At 2002-02-22 01:36, Richard Uhtenwoldt wrote:

>So, congratulations, you've written call/cc in Haskell. I think.

Yes.

    test2 :: CPS (IO ()) ();
    test2 = do
        {
        liftM (putStr "aa\n");
        ref <- liftM (newIORef Nothing);
        liftM (putStr "bb\n");
        flag <- peirceM (\c -> do
            {
            liftM (putStr "cc\n");
            liftM (writeIORef ref (Just c));
            liftM (putStr "dd\n");
            c True;
            liftM (putStr "ee\n");
            return False;
            });
        liftM (putStr "ff\n");
        if (flag) then do
            {
            liftM (putStr "gg\n");
            Just c' <- liftM (readIORef ref);
            liftM (putStr "hh\n");
            c' False;
            liftM (putStr "ii\n");
            }
         else do
            {
            liftM (putStr "jj\n");
            }
        };

ContMonad> doMonadCPS test2
aa
bb
cc
dd
ff
gg
hh
ff
jj

...which shows that the continuation passed in by peirceM works both 
inside and outside the call. Changing "c' False" to "c' True" gave this 
endless iteration:

ContMonad> doMonadCPS test2
aa
bb
cc
dd
ff
gg
hh
ff
gg
hh
ff
gg
hh
...

I assume by the magic of Haskell's tail recursion, this won't eat up 
space.

-- 
Ashley Yakeley, Seattle WA