假人的递归方案?

Posted

技术标签:

【中文标题】假人的递归方案?【英文标题】:Recursion schemes for dummies? 【发布时间】:2011-10-19 23:48:38 【问题描述】:

我正在寻找一些非常简单、易于理解的递归方案和核心递归方案(变形、变形、hylomorphism 等)的解释,这些解释不需要遵循大量链接,也不需要打开范畴论教科书。我确信我已经无意识地重新发明了许多这些方案,并在编码过程中将它们“应用”在我的脑海中(我相信我们中的许多人都有),但我不知道我的(共同)递归方案是什么使用被称为。 (好吧,我撒谎了。我刚刚读到其中的一些,这引发了这个问题。但在今天之前,我不知道。)

我认为这些概念在编程社区中的传播受到了人们往往会遇到的令人生畏的解释和示例的阻碍——例如在***上,但也在其他地方。

这也可能被他们的名字所阻碍。我认为还有一些替代的、更少数学的名称(关于香蕉和铁丝网的东西?),但我也不知道我使用的递归方案的更简洁的名称是什么。

我认为使用代表简单现实问题的数据类型的示例而不是二叉树等抽象数据类型会有所帮助。

【问题讨论】:

Jeremy Gibbons 有几篇论文可能是最好的介绍,因为它们清晰且在很大程度上是独立的。 “流表示改变器”(折叠和展开相结合),“程序理解的裂变”(变形和更多),“被低估的展开”(变形)。 cs.ox.ac.uk/people/publications/date/Jeremy.Gibbons.html 【参考方案1】:

非常笼统地说,变质只是fold 的轻微概括,变形是unfold 的轻微概括。 (并且一个hylomorphism只是一个展开,然后是一个折叠。)。它们通常以更严格的形式呈现,以使与范畴论的联系更加清晰。更密集的形式让我们能够区分数据(初始代数的必然有限乘积)和余数据(最终代数的可能无限乘积)。这种区别让我们保证永远不会在无限列表上调用折叠。变态和变形通常以这种有趣的方式编写的另一个原因是,通过对 F 代数和 F 代数(由函子生成)进行操作,我们可以一劳永逸地编写它们,而不是在一个列表上写一次,一次在一个列表上写一次。二叉树等。这反过来又有助于明确为什么它们都是一样的。

但从纯粹直觉的角度来看,您可以将 cata 和 ana 视为还原和产生,仅此而已。

编辑:多一点

变质(长臂猿)就像一个由内而外的水龙——它是一个折叠,然后是一个展开。因此,您可以使用它来拆除一个流并建立一个具有可能不同结构的新流。

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

然而,虽然“直观”的解释很简单,但链接的代码就不那么简单了,关于其中一些的博客文章可能有点复杂/令人生畏。

也就是说,除了组织同态之外,我认为动物园的其余部分不一定是你大部分时间都想直接思考的东西。如果你“得到”了 hylo 和 meta,你几乎可以单独用它们来表达任何东西。通常,其他态射的限制更多,而不是更少(但因此“免费”为您提供更多属性)。

【讨论】:

好的,谢谢,但这只是这三个 - 还有其他的。我希望有人会添加一个关于其他一些递归方案的答案。 大多数剩余的递归方案有点晦涩难懂,除了可能的变形,它很好地对应于我们在依赖语言中经常看到的类型的“归纳原则”。我还没有完全弄清楚所有类别理论是如何在这里发挥作用的,但我怀疑它会崩溃太可怕:) Paramorphism 就像一个折叠,但您可以查看“输入的其余部分”。折叠仅在遍历期间为您提供基本访问权限。【参考方案2】:

一些参考资料,从最理论上的类别(但与提供“领土地图”相关,可让您避免“点击大量链接”)到更简单且更独立的参考:

就“香蕉和铁丝网”词汇而言,这来自the original paper of Meijer, Fokkinga & Patterson(以及其他作者的续集),总而言之,它与不太可爱的替代品一样重符号:“名字"(香蕉等)只是它们所挂钩的结构的 ascii 符号的图形外观的捷径。例如,变形(即折叠)用(| _ |) 表示,par-with-parenthesis 看起来像“香蕉”,因此得名。这是最常被称为“坚不可摧”的论文,因此如果我是你,我不会首先查找它。

这些递归方案的基本参考资料(或者更准确地说,这些递归方案的关系方法)是 Bird & de Moor 的 Algebra of Programming(这本书不可用,除非作为按需打印,但有可用的副本二手的,应该在图书馆里)。它包含对无点编程的更节奏和详细的解释,如果仍然是“学术性的”:这本书介绍了一些类别理论词汇,尽管是以自包含的方式。然而,练习(你不会在论文中找到)会有所帮助。

Sorting morphisms by Lex Augustjein,对各种数据结构使用排序算法来解释递归方案。通过构造,它几乎是“傻瓜的递归方案”:

本演示文稿提供了介绍各种态射的机会 一种简单的方法,即作为在函数式编程中有用的递归模式,而不是通过类别理论的通常方法,这对于普通程序员来说往往是不必要的恐吓。

另一种进行无符号演示的方法是Jeremy Gibbons' chapter Origami Programming 中的The Fun of Programming,与前一种方法有一些重叠。它的参考书目提供了对该主题的介绍。

编辑:Jeremy Gibbons 只是让我知道他在阅读此问题后在book's webpage 上添加了指向整本书书目的链接。 享受

恐怕这最后两个参考文献只给出了 (cata|ana|hylo|para)morphisms 的可靠解释,但我希望这足以打破你可以在更多符号中找到的代数形式——沉重的出版物。除了这四种之外,我不知道(共)递归方案的任何严格的非分类理论解释。

【讨论】:

【参考方案3】:

Tim Williams 昨晚在 London Haskell 用户组就递归方案做了一场精彩的演讲,并为你提到的每个方案提供了一个激励性的例子。查看幻灯片:

http://www.timphilipwilliams.com/slides.html

在幻灯片的末尾有对所有常见嫌疑人(镜头、香蕉、铁丝网点菜等)的引用,您还可以在 Google 上搜索“Origami Programming”,这是一个不错的介绍,我以前没有遇到过.

视频上传后会显示在此处:

http://www.youtube.com/user/LondonHaskell

编辑大部分有问题的链接都在上面 huitseeker 的回答中。

【讨论】:

以上是关于假人的递归方案?的主要内容,如果未能解决你的问题,请参考以下文章

传奇gee引擎,智能假人,假人脚本,geeM2假人

如何将此递归解决方案转换为 DP 解决方案?

递归解决方案的动态规划解决方案

Java中背包的递归解决方案

Java 递归 - 引用传递的替代方案:

我的背包递归解决方案可以改进吗?