Reputation: 43843
I have this data type and I want to define a equality operator for it. Mlist should be an instance of Eq.
data Mlist a = Mlist [a]
instance Eq a => Eq (Mlist a) where
(==) :: [a] -> [a] -> Bool
The equality operator should allow me to check this (plus the ordering shouldn't matter):
m1 = Mlist [1,2,3]
m2 = Mlist [3,1,2]
-- then m1 equals m2
m3 = Mlist [3,2,1,5]
-- then m1 not equals m3
The top code isn't working, can anyone help with this?
Edit: Here is a new version, but it's not working...
instance Eq a => Eq (Mlist a) where
(==) :: (Eq a) => [a] -> [a] -> Bool
(==) [] [] = True
(==) [] _ = False
(==) _ [] = False
(==) (hd:tl) b = (==) tl $ delete hd b
Upvotes: 4
Views: 1332
Reputation: 7001
To address your edit: the new version does not work because instance declarations should not have type signatures. The type signature is given by the class.
The code is still incorrect, because you haven't accounted for the case where hd
is not in b
. In that case, delete hd b
is just b
, so in particular if tl == b
then you'll return True
, when you really should have returned False
.
Upvotes: 0
Reputation: 3393
To make Mlist a
an instance of Eq
, you have to define either
(==) :: Mlist a -> Mlist a -> Bool
or
(/=) :: Mlist a -> Mlist a -> Bool
In essence, you need to implement a function which can determine whether two lists equal. Since Eq
is the only constraint, you can use the help from Data.List.\\
. For example:
instance Eq a => Eq (Mlist a) where
Mlist xs == Mlist ys = length xs == length ys && null (xs \\ ys)
Upvotes: 9