Can the CPS-styled `call/cc` be written in terms of a hypothetical non-CPS-styled `cc'`?

牧云@^-^@ 提交于 2019-12-10 18:13:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!