首页 > 解决方案 > CPS 风格的 `call/cc` 是否可以用假设的非 CPS 风格的 `cc'` 来编写?

问题描述

在支持延续的语言中,例如 Scheme、Ruby 和 Haskell,假设有一个cc'不带参数并返回当前延续的函数,因此通过调用获得延续的调用者cc'可以在任何地方调用延续它喜欢。

cc'可以call/cc通过将恒等函数作为参数传递给 CPS 风格的 来编写call/cc

相反,CPS-styledcall/cc可以用 non-CPS- styled 来写cc'吗?

标签: rubyhaskellschemecontinuationscontinuation-passing

解决方案


这是我的尝试(警告:我是一个没有经验的策划者)。让get-cc成为返回当前延续的函数。

(define (get-cc)
  (call-with-current-continuation (lambda (k) k)))

然后,我们可以定义:

(define (callCC f)
  (let ((w (get-cc)))
    (if (pair? w)
      (car w)
      (f (lambda (x) (w (cons x '())))))))

第一次调用此函数时,w将绑定到当前延续。所以,(pair? w)是假的,我们f用 continuation调用(lambda (x) (w (cons x '()))

w被调用时f(带有参数),然后再次输入(cons x '())的主体,现在绑定到。现在,是真的,我们可以返回which is 。letw(cons x '())(pair? w)(car w)x

可以说,pair wrapper 用于区分什么是“the continuation for f”和“the result from f ”。

快速测试表明这是可行的,但我并不完全相信它的正确性。

您可能注意到它w绑定到不同类型的值。这就是为什么我使用像 Scheme 这样的无类型语言而不是 Haskell 的原因。


推荐阅读