方案:我们如何用lambda编写递归过程?

时间:2012-06-27 16:59:58

标签: recursion lambda scheme sicp

我正在通过Brain harvey进行计算机编程的结构和解释。我遇到了这个问题,我无法弄明白该怎么做。

我们如何在Scheme中用lambda编写递归过程?

3 个答案:

答案 0 :(得分:8)

TL; DR:使用名为let(如果您正在立即执行递归函数)或rec(如果要保存递归函数以便以后执行)。


通常的方式是使用letrec或在幕后使用letrec的内容,例如名为letrec的内容。以下是使用(factorial 10)的{​​{1}}版本:

letrec

使用名为(letrec ((factorial (lambda (x) (if (< x 1) 1 (* (factorial (- x 1)) x))))) (factorial 10)) 的同样的事情:

let

这里的关键理解是两个版本完全相同。名为(let factorial ((x 10)) (if (< x 1) 1 (* (factorial (- x 1)) x))) 的只是一个扩展为let表单的宏。因为命名的letrec版本较短,这通常是编写递归函数的首选方法。


现在,您可能会问,如果要直接返回递归函数对象,而不是执行它,该怎么办?您也可以使用let

letrec

虽然没有使用名为(letrec ((factorial (lambda (x) (if (< x 1) 1 (* (factorial (- x 1)) x))))) factorial) ,但使用的是rec,但它也是此的简写:

let

在这里使用(rec (factorial x) (if (< x 1) 1 (* (factorial (- x 1)) x))) 的好处是你可以将函数对象分配给变量并稍后执行它。

rec

创建递归函数的理论和“纯粹”方法是使用Y combinator。 :-)但是大多数实用的Scheme程序都没有使用这种方法,因此我不会进一步讨论它。

答案 1 :(得分:5)

无需写两次因子体;)

(((lambda (f)
   (lambda (x)
     (f f x)))
 (lambda (fact x)
   (if (= x 0) 1 (* x (fact fact (- x 1)))))) 5)

答案 2 :(得分:3)

这是一个递归函数,使用lambda

计算阶乘5
((lambda (f x)
  (if (= x 0)
      1
      (* x (f f (- x 1)))))
 (lambda (f x)
  (if (= x 0)
      1
      (* x (f f (- x 1)))))
 5)

当您在Drracket中运行此程序时,您将获得120:)