如何在Haskell中为一个类创建一个等值运算符?

4

我有一个数据类型,并且想要为它定义相等运算符。Mlist应该是Eq的实例。

data Mlist a = Mlist [a]

instance Eq a => Eq (Mlist a) where
    (==) :: [a] -> [a] -> Bool

等式运算符应该允许我检查这个(而且顺序也不应该有影响):

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

顶部代码不起作用,有人能帮忙吗?

编辑: 这是一个新版本,但它也不起作用...

instance Eq a => Eq (Mlist a) where
    (==) :: (Eq a) => [a] -> [a] -> Bool
    (==) [] [] = True
    (==) [] _ = False
    (==) _ [] = False
    (==) (hd:tl) b = (==) tl $ delete hd b

1
你需要定义 (==) :: Eq a => Mlist a -> Mlist a -> Bool,而不是 (==) :: (Eq a) => [a] -> [a] -> Bool - nymk
2
你确定不想使用 Data.Set 吗? - luqui
2个回答

9
为了使 Mlist a 成为 Eq 的实例,你需要定义以下内容之一:
(==) :: Mlist a -> Mlist a -> Bool

或者

(/=) :: Mlist a -> Mlist a -> Bool

本质上,您需要实现一个函数,该函数可以确定两个列表是否相等。由于Eq是唯一的约束条件,因此您可以使用来自Data.List.\\的帮助。例如:

instance Eq a => Eq (Mlist a) where
    Mlist xs == Mlist ys = length xs ==  length ys && null (xs \\ ys)

不知道这个\. 真不错 :) - manojlds

0
针对您的编辑:新版本不起作用,因为实例声明不应该有类型签名。类型签名由类给出。
代码仍然不正确,因为您没有考虑到hd不在b的情况。在这种情况下,delete hd b只是b,因此特别是如果tl == b,那么您将返回True,但您真正应该返回False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接