omega
omega

Reputation: 43843

How to create a equality operator for a class in Haskell?

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

Answers (2)

Ben Millwood
Ben Millwood

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

nymk
nymk

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

Related Questions