【问题标题】:Length function in " The Seasoned Schemer"《老谋深算》中的长度函数
【发布时间】:2012-06-14 16:06:44
【问题描述】:

我一直在阅读 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

【问题讨论】:

    标签: scheme seasoned-schemer


    【解决方案1】:

    在“经验丰富的计划者”中,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 过程与上面定义的完全相同,您不应该重新定义它。本章这部分的目的是达到我的答案中显示的第二个定义。

    【讨论】:

      猜你喜欢
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      • 2017-11-12
      • 2021-05-26
      • 2016-10-25
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多