其他一些人已经简要地提到了fgl
和Martin Erwig的Inductive Graphs and Functional Graph Algorithms,但它可能值得写出一个实际上给出感应表示方法背后的数据类型的意义的答案。
在他的论文,Erwig提出了以下几种类型:
type Node = Int
type Adj b = [(b, Node)]
type Context a b = (Adj b, Node, a, Adj b)
data Graph a b = Empty | Context a b & Graph a b
(在fgl
的表现略有不同,并充分利用类型类 - 但这个想法基本上是相同的。)
Erwig描述了一个多图,其中节点和边有标签,并且所有边都是直接指向的。 A Node
有某种类型的标签a
;边缘有某种类型的标签b
。 A Context
简单地(1)标记边缘的列表,其指向到特定节点,(2)所讨论的节点,(3)节点的标签,以及(4)标记边缘的列表,指向,从节点。然后可以将Graph
作为Empty
或作为Context
合并(与&
)归纳为现有Graph
。
由于Erwig指出,我们不能随意生成Graph
与Empty
和&
,因为我们可能会产生与Cons
和Nil
构造,或Leaf
和Branch
一个Tree
列表。太不像列表(正如其他人所提到的),不会有任何规范的Graph
表示。这些是至关重要的差异
然而,是什么让这表示如此强大,所以类似的列表和树的典型哈斯克尔表示,是这里的Graph
数据类型是归纳定义。事实上,列表是归纳定义的,它允许我们在它上简洁地匹配模式匹配,处理单个元素,并递归处理列表的其余部分;同样,Erwig的归纳表示允许我们一次递归地处理一个图形Context
。这种图形表示方式适用于在图形上绘制图形的简单定义(gmap
),以及在图形上执行无序折叠的方法(ufold
)。
此页面上的其他评论很棒。然而,我写这个答案的主要原因是,当我读到诸如“图不是代数的”这样的短语时,我担心有些读者不可避免地会忘记没有人找到表示图表的好方法的(错误的)印象在Haskell中允许对它们进行模式匹配,对它们进行映射,对它们进行折叠,或者通常做一些我们习惯使用列表和树的很酷,功能性的东西。
您可能会感兴趣Martin Erwig关于函数图算法的论文:http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01。这个'fgl'包被开发出来了。 – 2012-03-16 08:39:41