5

我一直在阅读 The Seasoned Schemer 并且遇到了长度函数的这个定义

(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在长度定义中写了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
4

1 回答 1

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上面定义的过程完全相同的过程,您不应该重新定义它。本章这一部分的目的是达到我的答案中显示的第二个定义。

于 2012-06-14T16:43:57.410 回答