我完全迷失了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年的结果。
答案 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
设置为每次迭代的延续,最后一次设置为18
,16
和{{1}并处理2015
。
调用2
时,您会回到(a-continuation 2014)
的处理,但不是递归,而是告诉延续的答案是2
,因此您得到2014