I'm trying to implement a simple Set in Haskell, and am getting stuck with how to express class constraints for the elements it contains.
The Set type class is fairly simple:
class Set s where
empty :: s a
isEmpty :: s a -> Bool
insert :: s a -> a -> s a
contains :: s a -> a -> Bool
A trivial implementation of a Set is a binary search tree:
data BinarySearchTree a = Node a (BinarySearchTree a) (BinarySearchTree a) | Leaf
I'm getting somewhat stuck when it comes to declaring the correct class constraints, however:
Setrequires, at the very least, the ability to decide whether two elements are equal - its values need to have an instance ofEq.BinarySearchTreerequires its elements to have an instance ofOrd, since each node needs to have the smaller element on the left and the bigger on the right.
The first, simple solution is to update Set's signature to require a to have an instance of 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
Implementing an instance of Set for BinarySearchTree is not a problem: Ord implies Eq, so I can "override' the class constraints.
What if, however, BinarySearchTree required some exotic class contraints, ones that are entirely incompatible with Eq? How do I express these and keep the type checker happy?
The only way I can think of is to add a class constraint on BinarySearchTree, something like:
data Ord a => BinarySearchTree a = Node a (BinarySearchTree a) (BinarySearchTree a) | Leaf
Unfortunately, this does not seem to satisfy the type checker: even though the declaration guarantees that BinarySearchTree must contain elements with an Ord instance, this constraint doesn't seem to carry over to functions that use BinarySearchTree - it's as if the class constraint only applied to the data constructors, but were then forgotten about.
What am I missing? Is there an elegant solution for what I'm trying to do, or even a solution at all?
EqonSet,OrdonBinarySearchTree" thing but I can't get that to compile anymore....