【发布时间】:2014-08-26 15:23:14
【问题描述】:
我正在尝试在 Haskell 中实现一个简单的 Set,但我一直不知道如何为它包含的元素表达类约束。
Set 类型类相当简单:
class Set s where
empty :: s a
isEmpty :: s a -> Bool
insert :: s a -> a -> s a
contains :: s a -> a -> Bool
Set 的一个简单实现是二叉搜索树:
data BinarySearchTree a = Node a (BinarySearchTree a) (BinarySearchTree a) | Leaf
然而,在声明正确的类约束时,我有点卡住了:
-
Set至少需要能够确定两个元素是否相等 - 它的值需要有一个Eq的实例。 -
BinarySearchTree要求其元素具有Ord的实例,因为每个节点都需要在左侧具有较小的元素,在右侧具有较大的元素。
第一个简单的解决方案是更新Set 的签名以要求a 拥有Eq 的实例:
class Set s where
empty :: Eq a => s a
isEmpty :: Eq a => s a -> Bool
insert :: Eq a => s a -> a -> s a
contains :: Eq a => s a -> a -> Bool
为BinarySearchTree 实现Set 的实例不是问题:Ord 隐含Eq,因此我可以“覆盖”类约束。
但是,如果BinarySearchTree 需要一些与Eq 完全不兼容的奇异类约束怎么办?我该如何表达这些并让类型检查器满意?
我能想到的唯一方法是在BinarySearchTree 上添加一个类约束,例如:
data Ord a => BinarySearchTree a = Node a (BinarySearchTree a) (BinarySearchTree a) | Leaf
不幸的是,这似乎不能满足类型检查器的要求:即使声明保证 BinarySearchTree 必须 包含带有 Ord 实例的元素,这个约束似乎并没有延续对于使用 BinarySearchTree 的函数 - 就好像类约束仅适用于数据构造函数,但随后被遗忘了。
我错过了什么?对于我正在尝试做的事情,是否有一个优雅的解决方案,甚至是一个解决方案?
【问题讨论】:
-
我的观点似乎有一点不正确:我确定我已经设法完成了整个“
EqonSet,Ordon @987654349 @" 的东西,但我不能再编译了.... -
注意:这个问题与另一个问题有关:stackoverflow.com/questions/25345055/…。不确定它是否足够接近以被视为重复...
-
我不确定它们是否符合重复的条件,尽管它们似乎都来自同一个根本问题。无论哪种方式对我来说都很好,我不会因为我的问题作为重复而被冒犯。
标签: haskell