我试图在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)
答案 0 :(得分:3)
问题在于,您尝试将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函数。