在Scheme中调用Continuation CC

时间:2015-01-28 11:48:11

标签: scheme callcc continuation

我完全迷失了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年的结果。

3 个答案:

答案 0 :(得分:2)

我明白了

> (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>))))

当你致电延续时,

(a-continuation 2014)

你评估

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

当然是2018年。

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

答案 1 :(得分:0)

这可能真的令人困惑。但也许一个更简单的例子可以提供帮助(取自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。现在我们已在return中将cont设置为call/cc。在此范围内,cont是一个带有1个参数的过程。当被调用时,它将评估该参数。这是有趣的部分,当您评估程序时,评估将在call/cc的位置恢复。因此,当您致电(return 22)时,它将22评估为(+ 1 (call/cc ...)),结果为23

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

答案 2 :(得分:0)

调用(myfunction number? '(18 16 2015 2))时,您将a-continuation设置为每次迭代的延续,最后一次设置为1816和{{1}并处理2015

调用2时,您会回到(a-continuation 2014)的处理,但不是递归,而是告诉延续的答案是2,因此您得到2014