我试图理解add1在这个递归示例中是如何使用的:

(define (my-length a-list)
  (if (empty? a-list)
      0
      (add1(my-length (rest a-list)))))

如果给定(my-list '(1 2 3 4))程序将返回数字4。
我知道,在函数my-lenght的每次迭代之后,代码都会分解列表,直到列表为空我不明白的是(add1)如何将每次迭代都添加到函数中。

最佳答案

为了另一种解释:
我们从这里开始

(my-length '(a b c d))

通过将参数填充到函数中
(if (empty? '(a b c d))
  0
  (add1 (my-length (rest '(a b c d)))))

显然,'(a b c d)不是空的。因此,对if的“else”情况进行评估:
(add1 (my-length (rest '(a b c d))))
(add1 (my-length '(b c d)))

现在,(my-length '(b c d))是什么意思如果我们把函数体复制粘贴到最后一行,我们得到:
(add1 (if (empty? '(b c d))
        0
        (add1 (my-length (rest '(b c d))))))

持续的。。。
(add1 (add1 (my-length (rest '(b c d)))))
(add1 (add1 (my-length '(c d))))

这将一直持续到我们得到一个空列表:
(add1 (add1 (add1 (add1 (if (empty? '())
                              0
                              (add1 (my-length (rest '()))))))))

'()为空,因此if语句返回0:
(add1 (add1 (add1 (add1 0))))
(add1 (add1 (add1 1)))
(add1 (add1 2))
(add1 3)
4

这就像我们在不断地深入到函数中,因为对于我们所采取的每一步,我们都需要再做一步来实际评估我们所拥有的。
这与(add1 '(a b c d))有何不同?从评估结果可以看出,add1实际上从未应用于a、b、c或d。我们甚至从未检查过列表中的内容你可以有一个由四个列表组成的列表,每个列表都包含一个列表,并且它的计算结果都是一样的。
具体来说,说(add1 '(a b c d))就像说“1加草莓是什么?”,而您的功能更像:
“这张单子上有多少东西?”
“好吧,如果你在上面看不到任何东西((first my-list)),那么肯定没有。”
“好吧,好吧……我看到上面有个‘A’!”
“太好了把它拿出来名单上至少有一个。”
“好吧,剩下的是多少?”
“我们再试一次怎么样?只需从列表顶部取出项目,直到列表为空然后,我们再把它放在一起,边走边数。”
“好吧,我已经把它们全拿出来了我现在要把它们放回去:D,那是1;C,那是2;B,那是3;A,那是4!”
“给你,名单上有4个!”

10-04 14:03