【问题标题】:Call Continuation CC in Scheme在 Scheme 中调用 Continuation CC
【发布时间】:2015-03-27 07:26:20
【问题描述】:

我完全迷失了 Scheme 中的呼叫继续。有人可以帮我做这个例子吗?

 #lang scheme


(define a-continuation '*dummy-value*)

(define (myfunction what? l)
  (cond ((null? l) 0)
        ((what? (car l)) 
         (+ 1 (call/cc (lambda (f)
                         (set! a-continuation f)
                         (myfunction what? (cdr l))))))
        (else (myfunction what? (cdr l)))))

(myfunction number? '(18 16 2015 2))

(a-continuation 2014)           

我了解第一个结果 (3),但我不了解 2017 年的结果。

【问题讨论】:

  • 看看this是否有帮助。

标签: scheme callcc continuation


【解决方案1】:

我明白了

> (myfunction number? '(18 16 2015 2))
4
> (a-continuation 2014)
2018

但是这种“据我所知”的解释应该仍然有效。

(我希望继续在其参数中添加 1。我错了,所以我也试图向自己解释这一点。)

如果删除延续部分,myfunction 是一个计算谓词 what? 包含多少元素的函数。

在 REPL/交互窗口中玩一点,

> (myfunction number? '(1))
1
> (a-continuation 1)
2
> (a-continuation 2)
3

> (myfunction number? '(1 2 3 4 5 6 7 8 9 10))
10
> (a-continuation 1)
11
> (a-continuation 2)
12
> (a-continuation 3)
13

> (myfunction even? '(1 2 3 4 5 6 7 8 9 10))
5
> (a-continuation 1)
6
> (a-continuation 2)
7
> (a-continuation 3)
8

人们可以从这种模式中怀疑延续将myfunction 找到的元素数量添加到它的参数中。

这是我对为什么会这样的解释:

如果您将每个call/cc 视为一个“洞”,以后可以通过调用捕获的延续来填充,那么第一个是

(+ 1 <hole>)

第二个

(+ 1 (+ 1 <hole>))

以此类推,创建一个添加“链”,每次谓词成立时添加一个。
(即捕获“等待”继续继续的整个递归,而不仅仅是最里面的调用。)

所以

(myfunction number? '(18 16 2015 2))

创建看起来像的东西

(+ 1 (+ 1 (+ 1 (+ 1 <hole>))))

当你调用 continuation 时,

(a-continuation 2014)

你评价

(+ 1 (+ 1 (+ 1 (+ 1 2014))))

当然是 2018 年。

(免责声明:这可能是完全错误的。

【讨论】:

  • 你是对的@molbdnilo。在 call/cc 中,f 是一个接受一个参数的过程。而那个参数就是返回值。当您调用您(绑定到a-continuation)的过程时,它将在您的示例中返回它的参数2014。这将在上面进行评估。您唯一忘记的是0 myfunctionnull? 列表上调用时返回。
【解决方案2】:

这真的很令人困惑。但也许一个更简单的例子会有所帮助(取自here

(define return #f) 

(+ 1 (call/cc 
       (lambda (cont) 
         (set! return cont) 
         1))) ;; <--- (+ 1 1)
 > 2
 (return 22)
 > 23

当您评估(+ 1 (call/cc ...)) 时,您会得到2。因为(call/cc ...)部分的返回值是1。现在我们在call/cc 中将return 设置为cont。在此范围内,cont 是一个带有 1 个参数的过程。当被调用时,它将评估该参数。这是有趣的部分,当您评估程序时,评估会在call/cc 的位置恢复。因此,当您调用(return 22) 时,它将在(+ 1 (call/cc ...)) 中评估为22,从而产生23

希望这很清楚。在我链接到的页面中,还有其他更复杂的示例。

【讨论】:

  • 谢谢。我理解你的例子,但我不明白我的例子。我认为我应该有 (+ 1 (2014),所以 2015 但我得到 2018。
  • 继续执行myfunction。您为a-continuation 设置的每个循环都设置了一个新值。因此,对于每个递归,您都会得到 (+ 1 ...),而最后一次递归得到 0。因此,对于每个 what? 为真的元素,您将 2014 添加到 1。
【解决方案3】:

当调用(myfunction number? '(18 16 2015 2)) 时,您将a-continuation 设置为每次迭代的延续,以及处理18162015 和处理2 的最后一个迭代。

当调用(a-continuation 2014) 时,你会返回到2 的处理,但不是递归,而是告诉继续的答案是2014,因此你得到(+ 1 (+ 1 (+ 1 (+ 1 2014)))) ; ==&gt; 2018

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 2019-03-19
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 2017-11-14
    • 2015-09-04
    相关资源
    最近更新 更多