我正在阅读Purely Functional Data Structres并尝试解决他们在haskell中提供的练习。
我已经以标准方式Tree
定义了data Tree a = Empty | Node a (Tree a) (Tree a)
我想将Set
定义为Tree
,其中节点是Ord
的实例。有没有办法在Haskell中表达这一点?每当我想要将一些数据结构表示为树时,像type Set = Tree Ord
或我认为重新实现树的东西?
答案 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
这就是使用类型类的方式。