Little Schemer:length0和mk-length

时间:2013-11-01 04:31:57

标签: scheme the-little-schemer

这个小阴谋者在page 165上给出了以下函数,因为函数 length 0 。但这是如何工作的?看起来 length lambda 被传递给 mk-length lambda ,它使用 length lambda <评估 length lambda / em>本身作为参数传递。那么,当评估底部的(length (cdr l))length只是长度lambda 本身。但 length lambda 有两个参数:lengthl。那么(length (cdr l))怎么能理解呢?

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

1 个答案:

答案 0 :(得分:5)

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

  

答:如果我们此时可以创建 mk-length 的另一个应用 eternity ,该怎么办?
   B:那只会把问题推迟到一个,而且,我们怎么能这样做?
   A:好吧,因为没有人关心我们传递给 mk-length 的函数,我们最初可以传递 mk-length
   B:这是正确的想法。然后我们在 eternity 上调用 mk-length ,并在 cdr 上调用它的结果,这样我们就可以再获得一块塔。<登记/>    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:所有名字都相同,但有些名字比其他名字更相等    A:是的:只要我们始终使用这些名称,我们就可以了    B: mk-length 的名称远远超过 length 。如果我们使用像 mk-length 这样的名称,则会不断提醒 mk-length 的第一个参数是 mk-length 。< / p>

page 166上,作者显示了一个适用于长度为0或1(即≤1)的列表的版本。最后,在page 167上,他们可以使用适用于任何长度列表的版本。 的工作方式在另一个问题中有更详细的描述:

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