我一直在阅读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
答案 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
程序,你不应该重新定义它。本章这一部分的目的是达到我的答案中所示的第二个定义。