4

小计划者在第 165 页上给出了以下内容,仍然是函数长度0。但这是如何工作的?看起来长度 lambda被传递给mk-length lambda ,它使用长度 lambda本身作为参数传递来评估长度 lambda 。那么,当在底部被评估时只是长度 lambda本身。但是长度 lambda需要两个参数 curried:和. 那么怎么可能有意义呢?(length (cdr l))lengthlengthl(length (cdr l))

((lambda (mk-length)
   (mk-length mk-length))
 (lambda (length)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (add1
                (length (cdr l))))))))
4

1 回答 1

5

Little Schemer正在构建一个函数,该函数适用于越来越长的列表。长度≤0的部分原因在于它仅适用于长度小于或等于零的列表(并且由于没有负长度的列表,这意味着长度为零的列表)。您故意显示的代码仅适用于长度为零的列表。事实上,这甚至在第 165 页的文字中指出:

A:如果我们可以在这一点上创建另一个mk-lengtheternity的应用程序会怎样?
B:那只会把问题推迟到一个人身上,而且,我们怎么能这样做呢?
A:好吧,既然没有人关心我们传递给mk-length 的函数是什么,我们最初可以将它传递给mk-length 。
B:这是正确的想法。然后我们在eternity上调用mk-length并在cdr上调用this 的结果,以便我们获得更多的塔的一部分。A:那么这仍然是长度0

((lambda (mk-length)
   (mk-length mk-length))
 (lambda (length)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (add1
                (length (cdr l))))))))

B:是的,我们甚至可以使用mk-length代替length

((lambda (mk-length)
   (mk-length mk-length))
 (lambda (mk-length)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (add1
                (mk-length (cdr l))))))))

A:我们为什么要这样做?
B:所有名字都是平等的,但有些名字比其他名字更平等。
答:是的:只要我们始终如一地使用名称,我们就可以了。
B: mk -length是一个比length更平等的名字。如果我们使用像mk-length这样的名称,它会不断提醒我们 mk-length 的第一个参数mk -length

第 166 页,作者展示了一个适用于长度为 0 或 1(即≤1)的列表的版本。最后,在第 167 页,他们得到了一个适用于任意长度列表的版本。在另一个问题中更详细地描述了它是如何工作

您可能还会发现以下感兴趣的问题:

于 2013-11-01T14:17:19.633 回答