【发布时间】:2015-08-03 23:18:55
【问题描述】:
我一直在阅读文章 Origami Programming by Jeremy Gibbons 并且无法弄清楚 unfoldR 和 unfoldF 函数如何为 Rose Trees 工作。
在论文中Rose Tree类型定义为:
data Rose α = Node α (Forest α)
type Forest α = List (Rose α)
unfoldR 和 unfoldF 函数是相互递归的,定义为:
unfoldR :: (β → α) → (β → List β) → β → Rose α
unfoldR f g x = Node (f x) (unfoldF f g x)
unfoldF :: (β → α) → (β → List β) → β → Forest α
unfoldF f g x = mapL (unfoldR f g) (g x)
看起来,除了一些小的边缘情况外,这些函数将无限递归。这两个相互递归的函数如何终止?
【问题讨论】:
-
当
unfoldF返回一个空列表时终止,即当g x返回一个空列表时。 -
没有理由终止它们。重要的是它们富有成效。它们支持玫瑰树上的模式匹配,因为只要需要节点结构,它就会被交付。在通过树的每条路径上,最终都找到具有空子树列表的节点可能并非如此。无限增长是可能的。 Haskell 识别归纳(所有路径必然有限)和互归纳(某些路径可能无限)结构:展开是生成互归纳结构的方式。它是如何工作的?而是问它什么时候起作用?按需提供。
-
将一个替换为另一个得到
unfoldR f g x = Node (f x) (mapL (unfoldR f g) (g x)),这将unfoldR简化为常规递归函数,而不是与unfoldF相互递归。正如@user5402 所说,当g x返回一个空列表时,unfoldF被映射到一个空列表中,从而导致零递归调用。
标签: haskell functional-programming