我一直在工作 小计划 学习方案并将PLT-Scheme用于我的环境。

小计划 对我的递归极大地帮助了我(现在对我来说很简单),但是我陷入了介绍“收藏家”的一部分,并将整个功能称为延续。

这是他们使用的示例代码。我了解递归元素,但我被卡住了,尤其是在lambda函数上 - 我的头脑无法遵循路径以及如何设置该lambda函数的论点(因为他们唯一的呼吁是在递归中再次称呼它们,所以有功能主体中没有具体使用)。

如果某人或者可以通过将功能递归递归到lambda收集器中,从而使我对计算道路进行分解,那可能会对我有所帮助。

;; 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 p s)
              (col (cons (car l) newl)
                (* (car l) p) s))))
         (else
           (even-only-collector (cdr l)
             (lambda (newl p s)
               (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 接收连续参数的功能(通常称为 k):

(define (list-sum l k)
  (if (null? l)
    ???
    (list-sum (cdr l) ???)))

基本模式存在,缺少的部分是有趣的事情发生的地方。续参数是一个期望接收结果的函数 - 因此,如果列表为null,很明显我们应该发送它 0, ,因为那是总和:

(define (list-sum l k)
  (if (null? l)
    (k 0)
    (list-sum (cdr l) ???)))

现在,当列表不是零的时候,我们用列表的尾巴递归将功能称为(换句话说,这是迭代),但是问题是延续是什么。这样做:

(define (list-sum l k)
  (if (null? l)
    (k 0)
    (list-sum (cdr l) k)))

显然是错误的 - 这意味着 k 最终将收到的总和 (cdr l) 而不是所有 l. 。相反,在那里使用新功能,该功能将总结 l 以及它收到的价值也是如此:

(define (list-sum l k)
  (if (null? l)
    (k 0)
    (list-sum (cdr l) (lambda (sum) (+ (car l) sum)))))

这越来越近,但仍然错了。但这是考虑事物的工作方式的好点 - 我们正在打电话 list-sum 延续本身将获得总和,并添加我们现在看到的第一项。我们忽略了这一事实,缺失的部分显而易见 k. 。我们需要的是 撰写 k 使用此功能 - 因此我们执行相同的总和操作,然后将结果发送到 k:

(define (list-sum l k)
  (if (null? l)
    (k 0)
    (list-sum (cdr l) (compose k (lambda (s) (+ s (car l)))))))

终于有效。 (顺便说一句,请记住这些 lambda 功能有其自己的“复制” l。)您可以尝试以下方法:

(list-sum '(1 2 3 4) (lambda (x) x))

最后注意,这与:

(define (list-sum l k)
  (if (null? l)
    (k 0)
    (list-sum (cdr l) (lambda (s) (k (+ s (car l)))))))

如果您将构图明确。

(您还可以在中级+lambda学生语言中使用此代码,然后单击“步进”按钮以查看评估如何进行 - 这将需要一段时间才能过去,但是您将看到延续功能如何嵌套,每个功能如何用自己的列表视图。)

其他提示

这是帮助您“获得更具体的想法”的一种方法。想象一下,是否对收藏家进行了定义:

(define (collector l p s)
  (display l)
  (newline)
  (display p)
  (newline)
  (display s)
  (newline))

您可以在基本情况下看到,如果您传递了空列表,它将用参数调用您的功能 '(), ,1和0。现在,使用一个元素列表,看看它将称呼您的功能。继续使用越来越长的列表,直到您弄清楚发生了什么。

祝你好运!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top