如何在 Haskell 中定义树状 DAG

Posted

技术标签:

【中文标题】如何在 Haskell 中定义树状 DAG【英文标题】:How to define a tree-like DAG in Haskell 【发布时间】:2013-04-30 16:37:33 【问题描述】:

如何在 Haskell 中最好地定义 有向无环图 (DAG)(字符串)(有一个根)?

我特别需要尽快在这个数据结构上应用以下两个函数:

    查找一个元素的所有(直接和间接)祖先(包括父母的父母等)。 查找一个元素的所有(直接)子元素。

我想到了[(String,[String])],其中每一对都是图形的一个元素,由其名称 (String) 和包含该元素的(直接)父级名称的字符串列表 ([String]) 组成。这个实现的问题是很难完成第二个任务。

您还可以再次使用[(String,[String])],而字符串列表 ([String]) 包含(直接)子项的名称。但是在这里,第一个任务很难完成。

我能做什么?有哪些选择?哪种方式最有效?

编辑: 再说一句:我也希望它能够轻松定义。我必须自己“手动”定义这种数据类型的实例,所以我想避免不必要的重复。

【问题讨论】:

data Family = Ego parents, children :: [String] ; type DAG = Map String Family?如果您存储父母和孩子,那么两者的查找操作都应该相当快。 或者有两张地图。一是从父母到孩子,二是从孩子到父母。选择最适合您的方式。 我在原始问题中添加了一个额外的注释,这使您的建议变得困难。 @MekeorMelire 定义您自己的类似地图的数据类型。你可以从type Map k v = [(k, v)]开始。 便宜,快速,正确,选择两个。呃,你可以有两个:1.容易/快速找到父母,2.容易/快速找到孩子,3.简单的表示。考虑权衡并做出选择。 【参考方案1】:

你看过the tree implemention in Martin Erwig's Functional Graph Library吗?每个节点都表示为一个包含其子节点和父节点的上下文。请参阅graph 类型类了解如何访问它。它可能不像您要求的那么简单,但它已经存在,经过充分测试且易于使用。我已经在一个大型项目中使用了十多年。

【讨论】:

知道它在 Haskell 地图上的速度吗?我想使用这个库,但我的图表很大。

以上是关于如何在 Haskell 中定义树状 DAG的主要内容,如果未能解决你的问题,请参考以下文章

Haskell中()的默认定义如何工作?

Haskell如何知道`xs`是函数定义中的列表?

如何在 Haskell 的“let”表达式中用“type”定义一个值?

如何在 Haskell 函数中对递归数据类型进行递归

如何在Haskell中产生无穷大?

如何向 Airflow 添加新的 DAG?