Recursion 方案尾部递归/迭代

Recursion 方案尾部递归/迭代,recursion,scheme,iteration,racket,tail-recursion,Recursion,Scheme,Iteration,Racket,Tail Recursion,我在scheme中构建了一个递归函数,它将在一些输入上重复给定的函数f,n次 (define (recursive-repeated f n) (cond ((zero? n) identity) ((= n 1) f) (else (compose f (recursive-repeated f (- n 1)))))) 我需要用尾部递归构建这个函数的迭代版本,如果我正确理解尾部递归,我认为我做得对 (define (iter-repeated f n)

我在scheme中构建了一个递归函数,它将在一些输入上重复给定的函数f,n次

(define (recursive-repeated f n)
  (cond ((zero? n) identity)
        ((= n 1) f)
        (else (compose f (recursive-repeated f (- n 1))))))
我需要用尾部递归构建这个函数的迭代版本,如果我正确理解尾部递归,我认为我做得对

(define (iter-repeated f n)
  (define (iter count total)
    (if (= count 0)
        total
        (iter (- count 1) (compose f total))))
  (iter n identity))

我的问题是,这实际上是迭代的吗?我相信我已经使用尾部递归正确地构建了它,但从技术上讲,它仍然将一系列操作推迟到count=0,在这里,它将执行它所堆积的任何组合。

您提出了一个好问题。您从构建递归过程(
(f(f(f)(f…)
)的递归过程(
递归重复
)转变为构建相同递归过程的迭代过程(
iter repeated

你认为你基本上做了同样的事情是对的,因为最终结果是一样的。你只是用两种不同的方式构建了同一条链。这是在实现中使用
compose
的“结果”

以这种方法为例

(define (repeat n f)
  (λ (x)
    (define (iter n x)
      (if (zero? n)
          x
          (iter (- n 1) (f x))))
    (iter n x)))
在这里,我们将返回一个等待输入参数的lambda,而不是提前构建整个函数调用链。指定输入参数后,我们将以迭代方式在lambda中循环
n次

让我们看看它的工作

(define (add1 x) (+ x 1))

;; apply add1 5 times to 3
(print ((repeat 5 add1) 3)) ;; → 8

为什么它会“推迟一系列操作直到n=0”?在
count=0
时,您只返回
total
,这可能是最简单的工作,几乎没有任何成本。好吧,但我想我要说的是,当您返回total时,它返回的是一堆操作,如
(合成方块(合成方块(合成方块(标识x)))
它在返回total而不是tail调用时对其进行计算。还是我想得太多了?@EddieV函数的所有参数都是在调用函数之前计算的。我明白了。我想那是有道理的,谢谢!虽然它是迭代的,但最终返回的是一个巨大而粗糙的lambda巢。诺米克在下面的回答给了你一个不乱的方法。