OpenDSA 完整目录

Chapter 30 Interpreting the Functional Language SLang

| 关于   «  4. 定义 SLang 2   ::   目录   ::   1. 参数传递机制  »

5. 打结

5.1. 高效地实现递归

接下来我们考虑如何在 SLang 2 中实现递归函数。在 λ-演算和 SLang 1 中,所有函数都是匿名的,不能调用自身。我们可以使用不动点组合子, 例如 \(Y\) 组合子。

let
     Y = fn (h) => (fn (x) => (h (x x)) fn (x) => (h (x x)))
     f = fn (g) => fn (n) => if (n === 0) then 1 else (n * (g (n - 1)))
in
     ((Y f) 5)
end

这种做法的问题是什么?

在 SLang 2 中,我们可以利用引用和赋值语句,用一种称为“打结” (tying the knot)的技术高效地实现递归。

为了体会这种技术的工作原理,请想一想下面这个程序的值是多少?

let
     dummyClosure = fn (n) => (n + 1)
in
     let
           f = fn (n) => if (n===0) then 1 else (n * (dummyClosure (n - 1)))
     in
           (f 5)
     end
end

我们怎样才能修改这个程序,把上面的函数 f 变成我们熟知的名字为 factorial 的(递归)函数,从而使上面程序的值变为 120?

提示:添加一条赋值语句,但该添加哪一条?添加在哪里?回答这些 问题,你就会明白为什么这种技术被称为“打结”。

5.2. 练习 TTK

下面的问题将帮助你熟悉 TTK 技术。要获得这道题的学分,你必须 连续三次正确完成这个随机化问题。

提交答案时,请记住给出完整的指称值,例如 [ "Num", 0 ] ,而 不只是 0 。

   «  4. 定义 SLang 2   ::   目录   ::   1. 参数传递机制  »

关闭窗口