1
(define length-it
  (lambda (ls)
    (length ls 0)))

(define length
  (lambda (ls acc)
    (if (null? ls)
        acc
        (length (cdr ls) (+ acc 1)))))

如何使用letrec将函数放入函数length体内length-it

输出应该是(length-it '(1 2 3))-> 3

4

1 回答 1

2

让我们从我们所拥有的开始:

(define length-it 
   (lambda (ls) 
      (length ls 0)))

但实际上,由于还调用了一个内置函数length,所以让我们将我们的函数重命名为my-length

(define my-length
  (lambda (ls acc)
    (if (null? ls)
        acc
        (my-length (cdr ls) (+ acc 1)))))

现在,

(define length-it 
   (lambda (ls) 
      (my-length ls 0)))
=
(define length-it 
   (let ((init 0))
     (lambda (ls) 
        (my-length ls 0))))       ;; (0)
=
(define length-it 
   (let ((init 0))                ;; (1)
     (lambda (ls) 
        (my-length ls init))))    ;; (2)

这行得通吗?指的是什么实体init(2)?是init(1)吗?

下一个,

=
(define length-it 
   (let ((init 0)                                      ;; (0)
         (my-length                                    ;; (1)
            (lambda (ls acc) 
               (if (null? ls) 
                   acc 
                   (my-length (cdr ls) (+ acc 1))))))  ;; (2)
     (lambda (ls) 
        (my-length ls init))))                         ;; (3)

现在行得通吗?(一定要在一个新的、新鲜的环境中测试这个,根本没有单独定义)。 my-length

不?为什么不?

该名称指的是什么实体init(3)?指的是什么my-length(3)?这个名字my-length(2)指的是什么?如果按原样my-length(2)引用它会起作用吗?既然它不起作用,必须参考上面定义的其他一些东西,但是我们那里还有更多的东西吗?my-length(1)my-length(3)my-length(2)my-lengthlet

那你能让它工作吗?你应该在let那里使用,还是其他原语letrec?两者完全一样吗?可能不是,否则他们为什么要两次命名同一个东西?那么我们可以尝试在那里使用另一个吗?它会不会确实像它应该做的那样my-length(2)引用?my-length(1)

它现在有效吗?

于 2021-02-17T07:41:57.037 回答