
On Tue, 2007-11-20 at 00:18 -0500, Dimitry Golubovsky wrote:
Hi,
I have been using plain non-monadic CPS for a while in my web-browser related stuff. Now I am tempted to switch from plain CPS to syntactically sweetened monadic style based on Continuation Monad, but I feel stuck with one important issue that I need an advice on.
In plain CPS, I may write:
type CPS x y = (y -> x) -> x
a :: x
a = f1 x $ \r -> case r of foo1 -> bar -- of type x foo2 -> f2 r $ \p -> ... -- something finally evaluating to a value of type x
So, if at any time I return a value of a final type (x) instead of doing something with given continuation, I abort/suspend the whole computation. This can happen at any function call depth. I can also save the continuation reference in some persistent place, to resume the remainder of computation later.
Now, I am trying to do the same with a Continuation Monad. But does anything similar exist in this monad? callCC is not exactly what I need because it only helps abort the inner computation, and what is returned, is a monadic value, not a final value. Besides, callCC defines a name of the function corresponding to the current continuation, and in order to use it, this name should be visible.
If I have
callCC $ \exit -> do foo ...
I cannot jump to `exit' from within foo unless `exit' is given to foo as an argument.
Any suggestions?
The best approach is probably to write a small variant of callCC usually called control that does abort if it's continuation isn't used and use that. I'm not a big fan of call/cc in general; I much prefer control. Control.Monad.Cont does export the Cont data constructor so you can easily add it yourself.