我试图在 Dr Racket 中创建“应用 N 次”功能,但不知道哪里出错了。我的代码似乎是正确的,但显然我遗漏了一些东西。下面打印的是代码和我遇到的错误。
(define (applyNtimes F n)
(lambda (x)
(if (= n 0) x
(F (applyNtimes F (- n 1))))))
(define cdr3 (applyNtimes cdr 3))
(cdr3 '(1 2 3 4 4 5))
这是我得到的错误:
cdr: contract violation
expected: pair?
given: #
预期的输出应该是
(4 4 5)
最佳答案
这就是问题所在,您正在尝试将 F
应用于 applyNtimes
的返回,但想一想,它会返回什么? 一个 lambda。
这意味着在您的情况下,我们正在尝试将 cdr
应用于 lambda,糟糕。
为了获取这个 lambda 的值以实际使用它,我们必须调用它。这样做很简单,只是改变一下
(F (applyNtimes F (- n 1))))))
到
(F ( (applyNtimes F (- n 1)) ;;Get the Lambda
x))))) ;; and apply it to x
为了理解这一点,让我们把它分开,首先我们将 F
应用于某些东西。因为在我们的例子中 F
实际上是 cdr
我们最好给它某种形式的对。
在此代码中,“Something”是将 (applyNTimes F (- n 1))
应用于 x
的结果。
好吧,这导致我们进行一些递归,我们真正要做的是
(F (F (F ... ((applyNTimes F (- n whatever)) x))))
好的,那么这个递归是如何结束的呢?好吧,当 (- n whatever)
为 0 时,我们返回 lambda
(lambda (x) x)
这真的把整个事情变成了
(F (F (F (F (F (F x))))))
这是我们想要的 applyNtimes 函数。
关于recursion - Dr Racket 中的 Lambda 递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13207503/