“The Seasoned Schemer”中的长度函数

时间:2012-06-14 16:06:44

标签: scheme seasoned-schemer

我一直在阅读The Seasoned Schemer,我遇到了 length 函数的定义

(define length
  (let ((h (lambda (l) 0)))
    (set! h (L (lambda (arg) (h arg))))
    h))

后来他们说:

  

(L(lambda(arg)(h arg)))的值是多少?这是功能

(lambda (l)
  (cond ((null? l) 0)
     (else (add1 ((lambda (arg) (h arg)) (cdr l))))))

我认为我并不完全理解这一点。我想我们应该自己定义 L 作为练习。我使用letrec在 length 的定义中写了 L 的定义。这是我写的:

(define length
  (let ((h (lambda (l) 0)))
    (letrec ((L
              (lambda (f)
                (letrec ((LR
                          (lambda (l)
                            (cond ((null? l) 0)
                                  (else
                                   (+ 1 (LR (cdr l))))))))
                  LR))))                  
    (set! h (L (lambda (arg) (h arg))))
    h)))

因此, L 将一个函数作为其参数,并返回另一个函数,该函数将列表作为其参数并在列表上执行递归。我的解释是正确还是无可救药?无论如何定义工作

 (length (list 1 2 3 4))  => 4

1 个答案:

答案 0 :(得分:3)

在“The Seasoned Schemer”中length最初的定义如下:

(define length
  (let ((h (lambda (l) 0)))
    (set! h (lambda (l)
              (if (null? l)
                  0
                  (add1 (h (cdr l))))))
    h))

在本书的后面,前面的结果已经推广,length被重新定义为Y!(应用顺序,命令式Y组合子),如下所示:

(define Y!
  (lambda (L)
    (let ((h (lambda (l) 0)))
      (set! h (L (lambda (arg) (h arg))))
      h)))

(define L
  (lambda (length)
    (lambda (l)
      (if (null? l)
          0
          (add1 (length (cdr l)))))))

(define length (Y! L))

问题中显示的length的第一个定义只是一个中间步骤 - 完全按照上面定义的L程序,你不应该重新定义它。本章这一部分的目的是达到我的答案中所示的第二个定义。