I’m trying to implement a Haskell Bag (multiset).
So far I’ve got this
data Bag a = EmptyBag | ListBag [(a, Integer)] deriving (Eq, Show)
emptyBag :: Bag a
emptyBag = EmptyBag
add :: a -> (Bag a) -> (Bag a)
add element EmptyBag = ListBag [(element,1)]
add element (ListBag bag)
| element `elem` map fst bag = ListBag bag -- will actually increment the count, and return the new bag.
I get the error
No instance for (Eq a)
arising from a use of `elem'
In the expression: element `elem` map fst bag
when compiling.
Is this because you can’t determine equality on two different types? How do I determine if the first element of an item in a Bag is already in the Bag?
Also, any tips on how to implement incrementing the count of a particular Item, and returning back the bag with the new (element,count) tuple?
The direct cause of your problem is that not all types are comparable for equality. You can restrict your type to only work with types that do provide an equality comparison by changing your type signature:
You might want to check out the multiset-comb and data-ordlist packages on Hackage for further implementation tips.
As a final note, I find the
EmptyBagconstructor a bit suspect: how does it differ from, e.g.,ListBag []?