是否有可能在Haskell中表示Set as Tree?

时间:2017-06-09 13:10:17

标签: haskell tree purely-functional

我正在阅读Purely Functional Data Structres并尝试解决他们在haskell中提供的练习。

我已经以标准方式Tree定义了data Tree a = Empty | Node a (Tree a) (Tree a) 我想将Set定义为Tree,其中节点是Ord的实例。有没有办法在Haskell中表达这一点?每当我想要将一些数据结构表示为树时,像type Set = Tree Ord或我认为重新实现树的东西?

2 个答案:

答案 0 :(得分:3)

您打算将树用作二叉搜索树(BST)吗?为了实现这一点,您需要所有操作来保留强大的BST属性:对于BST中的每个Node构造函数,左子树中的所有Node都包含小于当前{{1}中的元素的元素。 1}},右子树中的所有Node都包含更大的元素。

您绝对需要来保留该属性。一旦它不再成立,所有进一步的BST操作都将失去正确性保证。这个结论有后果。您不能公开该类型的构造函数。您无法公开操作以处理不保留BST属性的操作。

因此,对集合进行操作的每个操作都需要访问节点中约束类型的Node实例。 (好吧,除了几个特殊情况,比如检查一个集合是空的还是创建一个单例集,从而不必处理孩子的顺序。)

那时,您可以分享哪些树类型与其他用途?您无法共享操作。您不能使用构造函数。离开了,好吧......没什么用。您可以共享该类型的名称,无法用它做任何事情。

所以,不..你不能与其他只寻求任意二叉树的用途共享二叉搜索树数据类型。试图这样做会导致BST损坏。

答案 1 :(得分:2)

这正是来自Data.Set库的containers模块:

http://hackage.haskell.org/package/containers-0.5.10.2/docs/src/Data-Set-Internal.html#Set

您可以尝试阅读它的实现。如果您没有使用某些特殊语言扩展,type Set = Tree Ord将无法编译。但是你可能不想使用它们并且对以下函数更感兴趣:

insert :: Ord a => a -> Tree a -> Tree a
find   :: Ord a => a -> Tree a -> Maybe a
delete :: Ord a => a -> Tree a -> Tree a

这就是使用类型类的方式。