Dr Racket中的Lambda递归

3

我正在尝试在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))

这是我遇到的错误:

。涉及IT技术,请问需要进一步的上下文来帮助翻译吗?

cdr: contract violation
  expected: pair?
  given: #

预期输出应该是:
(4 4 5)
1个回答

4
这里有个问题,你试图将F应用于applyNtimes的返回值,但请思考一下,它返回了什么?一个lambda
这意味着在你的情况下,我们试图将cdr应用于一个lambda,哎呀。
为了获取这个lambda的值以便使用它,我们必须调用它。这很容易做到,只需改变
(F (applyNtimes F (- n 1))))))

to

(F ( (applyNtimes F (- n 1)) ;;Get the Lambda
     x))))) ;; and apply it to x

为了理解这个,让我们把它拆开来。首先我们要对某个东西应用 F。由于在我们的情况下 F 实际上是 cdr,所以最好给它一些形式的配对。
在这段代码中,“某些东西” 是将 (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函数。


1
这个可以运行,但你能解释一下语法吗?我的大脑在括号之间就炸了。如果我错了,请纠正我,但这是你正在做的吗?(cdr((lambda)x)) - T. Thomas
@TdotThomas 编辑了一个更完整的解释。 - daniel gratzer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接