繁体   English   中英

何时需要显式递归?

[英]When is explicit recursion necessary?

在Haskell中,尽可能在高阶函数(如折叠,贴图和展开)中编写尽可能多的代码是惯用的。 那么哪些代码不能用那些高阶函数编写? 何时需要显式递归?

让我们假设我们有一种没有递归的语言或类似的东西。 这意味着没有循环结构。 这也意味着我们也有(非递归)类型,因此我们无法形成Y-combinator并逃脱。 在这种语言中,我们真的很弱,与我们的许多工具分开。

但我们可以就这种语言提出一个非常好的问题。 也就是说,为了使它变得像没有这种限制的语言一样强大,我们必须给它最小的东西是什么?

事实证明有两个答案。

  1. 我们可以引入递归绑定器,比如let rec命令或类似Haskell的let ,它总是let rec 换句话说,一种允许我们let x = e in b定义let x = e in b的结构,使得如果xe是自由的,那么它被计算为等式x = e上的固定点。

  2. 我们可以引入函数fix :: (a -> a) -> a这样fix f在一步减少到f (fix f)

从上面的演示中可以清楚地看出,可以使用递归绑定器来实现fix 有点不太清楚的是递归绑定器可以使用修复从非递归绑定器实现,但是我们在这里:

let x = fix $ \this -> e

this是指整个表达式,最终结合为x这是我们想要什么。


那么为什么我会不遗余力地说出以上所有内容呢?

从本质上讲,我想说,只要你愿意考虑fix该列表,就不可能说递归必然是通过像map这样的HOF组合器来实现的。 我还想争辩说,该集合中的组合器实现的任何递归都可以使用递归绑定器“显式”完成。 他们同样强大。

当您考虑HOF组合器(如foldr / unfoldr时,有趣的部分会出现。 这些在技术上比fix /递归绑定器稍弱 优点是,如果您只使用一组选择的foldr / unfoldr原则构建编程语言,那么您可以获得一个非常丰富的子图灵完整语言,该语言可以完全或保证终止。

我想很多人发现递归数据定义比Mu / Fix / Nu类型更容易阅读。 这不是绝对必要的,但在那里非常有用。

类似地,您将通过使用递归为这样的数据类型编写可折叠/ Unfoldabe实例,但是一旦提供了这些实例,就不需要进行显式递归。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM