递归方案入门指南?

87

我正在寻找一些关于递归方案和核递归方案的非常简单易懂的解释(catamorphisms,anamorphisms,hylomorphisms等),而不需要跟随大量链接或打开范畴论教科书。我确信在编码过程中无意中“重新发明”了许多这些方案并在脑海中“应用”了它们(我相信我们许多人都是这样做的),但我不知道我使用的(共同)递归方案叫什么。 (好吧,我撒谎了。我刚刚读了一些关于它们的东西,这促使我提出这个问题。但在今天之前,我一无所知。)

我认为这些概念在编程社区中的扩散受到了阻碍,因为人们往往遇到了禁止解释和示例-例如在维基百科上,但也在其他地方。

它们的名称也可能会受到阻碍。 我认为有一些替代的、不那么数学化的名称(关于香蕉和铁丝网的某些内容?),但我对我使用的递归方案的更可爱的名称一无所知。

我认为使用表示简单实际问题的数据类型的示例,而不是抽象的数据类型(如二叉树),将有助于理解。


6
Jeremy Gibbons有几篇论文可能是最好的介绍,因为它们清晰易懂且大部分都是自包含的。其中包括“流表示改变器”(折叠和展开的组合),“程序理解的裂变”(参数形式和更多内容),以及“未被重视的展开”(反形式)。http://www.cs.ox.ac.uk/people/publications/date/Jeremy.Gibbons.html - stephen tetley
3个回答

49
极其宽泛地说,catamorphism 只是对 fold 的轻微概括,而 anamorphism 则是对 unfold 的轻微概括。(而 hylomorphism 就是一个 unfold 后跟一个 fold。) 通常它们以更严格的形式呈现,以使与范畴理论的联系更加清晰。更密集的形式让我们区分数据(初始代数的必然有限积)和协数据(最终余代数的可能无限积)。这种区别使我们保证从不对无限列表调用 fold。catamorphisms 和 anamorphisms 一般写法的另一个原因是通过操作 F-代数和 F-余代数(由 functors 生成)我们可以一劳永逸地编写它们,而不是一次在列表上,一次在二叉树上等等。这反过来有助于清楚地说明为什么它们都是同一件事。

但从纯直觉的角度来看,你可以将 cata 和 ana 视为减少和产生,就这样。

编辑:稍微多一点

metamorphism (Gibbons) 类似于一个内部 hylo -- 它是一个 fold 后跟一个 unfold。因此,您可以使用它来拆除流并使用可能具有不同结构的新流构建它。

Ekmett 发布了一份关于文献中各种方案的不错的“现场指南”:http://comonad.com/reader/2009/recursion-schemes/

然而,尽管“直观”的解释很简单,但链接的代码却不是那么简单,有些博客文章可能有点复杂/令人望而生畏。话虽如此,除了可能的histomorphisms外,我认为大多数时候你不需要直接思考其他变形。如果你理解了hylo和meta,你就可以仅用它们来表达几乎任何东西。通常,其他形态比较受限制,而不是更少(但因此可以为你提供更多属性“免费”)。

1
好的,谢谢,但那只是其中三个 - 还有其他的。我希望有人能提供关于其他递归方案的答案。 - Robin Green
3
剩余的递归方案大部分都比较难懂,除了可能的参数形式外,这种方案与我们经常在依赖语言中看到的类型归纳原理非常相似。我还没有完全弄清楚范畴论是如何发挥作用的,但我不认为会有什么太可怕的问题 :) - copumpkin
3
Paramorphism类似于fold,但你可以窥视“剩余的输入”。在遍历期间,fold只能给你基本的访问。 - stephen tetley

23

以下是一些参考资料,从最偏向范畴论的(但有助于提供一个“领域地图”,让您避免“点击大量链接”),到更简单且更自包含的:

  • 就“香蕉与铁丝网”词汇而言,这来自Meijer、Fokkinga和Patterson的原始论文(以及其他作者的续篇),总体上它与不那么可爱的替代方案一样充满符号: “名称”(香蕉等)只是与它们挂钩的构造的ascii符号外观的快捷方式。例如,范畴折叠(即折叠)用(| _ |)表示,带括号的par看起来像“香蕉”,因此得名。这篇论文最常被称为“难以理解”,因此如果我是你,这不是我要查找的第一件事。

  • 这些递归方案(更准确地说,对这些递归方案的关系方法)的基本参考资料是Bird & de Moor的《编程代数》(该书除了按需打印之外无法获取,但有二手副本可用,并且应该在图书馆中)。它包含了一个更有节奏和详细的无点编程解释,虽然仍然“学术”:该书以自包含的方式介绍了一些范畴论词汇。然而,练习(您在论文中找不到的)有所帮助。

  • Lex Augustjein的《排序形态》使用各种数据结构上的排序算法来解释递归方案。它几乎是“白痴递归方案”:

    这个演示提供了一个简单的方式来介绍各种形态,即作为函数式编程中有用的递归模式,而不是通过范畴论的通常方法,后者往往对普通程序员没有意义。

  • 另一种无符号演示的方法是Jeremy Gibbons 的章节折纸编程编程的乐趣中,与前一个章节有些重叠。它的参考书目介绍了该主题的介绍之旅。

    编辑:Jeremy Gibbons刚刚告诉我,在阅读此问题后,他已在书籍网页上添加了整本书的参考书目链接。享受

我担心这最后两个参考文献只能对(cata|ana|hylo|para)morphism提供一个坚实的解释,但我希望这足以撕开你可以在更注重符号表示的出版物中找到的代数形式主义。除了这四个外,我不知道任何严格的非范畴论解释(co-)recursion schemes。

17
昨晚,Tim Williams在伦敦Haskell用户组上发表了一场关于递归方案的精彩演讲,并且提供了每个方案的激励示例。查看投影片: http://www.timphilipwilliams.com/slides.html 。在幻灯片末尾有对所有常见的参考资料(镜头,香蕉,铁丝网ala carte等)的引用,您还可以搜索“折纸编程”,这是一个我以前没有接触过的不错的介绍。 视频将在上传到此处后发布:http://www.youtube.com/user/LondonHaskell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接