我正在通过Brain harvey进行计算机编程的结构和解释。我遇到了这个问题,我无法弄明白该怎么做。
我们如何在Scheme中用lambda编写递归过程?
答案 0 :(得分:8)
TL; DR:使用名为let
(如果您正在立即执行递归函数)或rec
(如果要保存递归函数以便以后执行)。
通常的方式是使用letrec
或在幕后使用letrec
的内容,例如名为let
或rec
的内容。以下是使用(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:)