问题
In a language which supports continuation, e.g. Scheme, Ruby, and Haskell, suppose there is a function cc'
which takes no argument and return the current continuation, so that the caller that obtains a continuation by calling cc'
can then invoke the continuation anywhere and as often as it likes.
cc'
can be written in terms of the CPS-styled call/cc
, by passing an identity function as an argument to call/cc
.
Conversely, can the CPS-styled call/cc
be written in terms of the non-CPS-styled cc'
?
回答1:
Here's my attempt (warning: I am an inexperienced schemer). Let get-cc
be the function returning the current continuation.
(define (get-cc)
(call-with-current-continuation (lambda (k) k)))
Then, we can define:
(define (callCC f)
(let ((w (get-cc)))
(if (pair? w)
(car w)
(f (lambda (x) (w (cons x '())))))))
The first time this function is called, w
is bound to the current continuation. So, (pair? w)
is false, and we call f
with continuation (lambda (x) (w (cons x '()))
.
When w
is called though f
(with argument (cons x '())
), then the body of the let
is entered again, where w
is now bound to (cons x '())
.
Now, (pair? w)
is true, and we can return (car w)
which is x
.
The pair wrapper is used so as to distinguish what is "the continuation for f
" from "the result from f
", so to speak.
A quick test shows this to be working, but I'm not completely confident of its correctness.
You probably noticed that w
is bound to values of different types. That is why I resorted to an untyped language like Scheme instead of Haskell.
来源:https://stackoverflow.com/questions/57361469/can-the-cps-styled-call-cc-be-written-in-terms-of-a-hypothetical-non-cps-style