帮助理解计划的延续
我一直和The Little Schemer一起学习Scheme,并使用PLT-Scheme来处理我的环境。
小Schemer帮助我很大程度上recursion(现在对我来说很简单),但是我被卡在介绍“collections家”的书的一部分,并且把整个函数作为一个整体继续。
这里是他们使用的示例代码。 我理解recursion元素,但我卡住了,特别是在lambda函数 – 我的头脑不能遵循path,如何设置该lambda函数的参数(因为他们唯一的调用是再次调用它们recursion,有在function体内没有具体的使用)。
如果有人能够或多或less地通过将函数recursion到lambda收集器中来计算我的计算path,那可能对我有帮助。
;; Build a nested list of even numbers by removing the odd ones from its ;; argument and simultaneously multiply the even numbers and sum the odd ;; numbers that occur in its argument. (define (even-only-collector l col) (cond ((null? l) (col (quote ()) 1 0)) ((atom? (car l)) (cond ((even? (car l)) (even-only-collector (cdr l) (lambda (newl ps) (col (cons (car l) newl) (* (car l) p) s)))) (else (even-only-collector (cdr l) (lambda (newl ps) (col newl p (+ (car l) s))))))) (else (even-only-collector (car l) (lambda (al ap as) (even-only-collector (cdr l) (lambda (dl dp ds) (col (cons al dl) (* ap dp) (+ as ds))))))))) ;; The collector function (define (collector newl product sum) (cons sum (cons product newl)))
先谢谢你!!
试一下简单来看看这是如何工作的。 例如,下面是一个list-sum
函数的版本,它接收一个continuation参数(通常称为k
):
(define (list-sum lk) (if (null? l) ??? (list-sum (cdr l) ???)))
基本模式在那里,缺less的部分是有趣的事情发生的地方。 continuation参数是一个函数,期望得到结果 – 所以如果列表为null,很明显,我们应该发送它0
,因为这是总和:
(define (list-sum lk) (if (null? l) (k 0) (list-sum (cdr l) ???)))
现在,当列表不为空时,我们用列表的尾部recursion地调用函数(换句话说,这是一个迭代),但是问题是延续是什么。 这样做:
(define (list-sum lk) (if (null? l) (k 0) (list-sum (cdr l) k)))
显然是错误的 – 这意味着k
最终会得到(cdr l)
的总和而不是所有的l
。 相反,在那里使用一个新的函数,它将总结l
的第一个元素以及它接收到的值:
(define (list-sum lk) (if (null? l) (k 0) (list-sum (cdr l) (lambda (sum) (+ (car l) sum)))))
这越来越近,但仍然是错误的。 但是,考虑一下事情是如何运作是一个很好的观点 – 我们用一个继续来调用list-sum
,这个延续本身就会得到全部的总和,并且把我们现在看到的第一个项目添加进去。 缺less的部分是显而易见的,因为我们忽略了k
。 我们需要的是用这个函数组合 k
– 所以我们做相同的求和操作,然后把结果发送到k
:
(define (list-sum lk) (if (null? l) (k 0) (list-sum (cdr l) (compose k (lambda (s) (+ s (car l)))))))
这是最后的工作。 (顺便说一下,请记住,每个lambda
函数都有它自己的“拷贝”)。你可以试试这个:
(list-sum '(1 2 3 4) (lambda (x) x))
最后请注意,这是一样的:
(define (list-sum lk) (if (null? l) (k 0) (list-sum (cdr l) (lambda (s) (k (+ s (car l)))))))
如果你明确的构图。
(你也可以在中间+ lambda学生语言中使用这段代码,并单击stepperbutton来查看评估过程如何进行 – 这将需要一段时间才能完成,但是你会看到连续函数是如何嵌套的有它自己的名单的看法。)
这里有一个方法可以帮助你“获得更具体的想法”。 想象一下,如果collections家是这样定义的:
(define (collector lps) (display l) (newline) (display p) (newline) (display s) (newline))
你可以在基本情况下看到,如果你传入一个空的列表,它会用参数'()
,1和0调用你的函数。现在,使用一个元素列表,看看它会叫你的function与。 继续处理更长和更长的列表,直到找出发生的事情。
祝你好运!