Haskell:如何检查两个列表是否相等

25

我想检查两个列表 AB 是否相等,即 a1 == b1, a2 == b2,...

我有一个可行的解决方案:

all (\x->x) zipWith $ (==) A B

另一个想法是递归实现:a:as,b:bs;检查a1==b1并使用剩余列表asbs调用函数。但是,有没有更简单和更易读的方法来实现这个?


如果您的列表始终具有相同的大小,则只需使用 A == B - Matvey Aksenov
1
如果您的列表大小不同,只需使用as == bs即可告诉您它们是否相等。 - Ingo
@Ingo和@mort的“working”解决方案将[1,2,3][1,2,3,4]视为相等,但(==)不会这样做。 - Matvey Aksenov
我没有提到列表长度,因为这很容易检查。但是,如果 == 是错误的话,如果两个列表的长度不相同,那就更好了。 - mort
Matvey - 我其实认为他的解决方案并不像他想要的那样有效。我应该明确说明这一点。 - Ingo
3个回答

54
你可以直接在它们上面使用 ==
> [1, 2, 3] == [1, 2, 3]
True
> [1, 2, 3] == [1, 2]
False

这是因为==Eq类型类的一部分,而列表有一个Eq实例,大致如下:

instance Eq a => Eq [a]

这意味着只要元素类型也实例化了Eq,列表就会实例化Eq。对于标准预定义类型而言,除了函数和IO操作之外,它们都是如此。


49

首先,hammar的回答是正确的,请接受他的答案。(编辑:你已经这么做了,谢谢。)

listA == listB

(我将在你的问题中挑剔一些细节,主要是为了未来通过谷歌搜索找到这个页面的初学者的利益。)

其次,AB不是列表:它们以大写字母开头,因此它们不能是变量。我要把它们称为listAlistB

第三,在您的工作解决方案中存在一个拼写错误:美元符号$应该在zipWith之前而不是之后。在您的问题中出现的方式会导致编译错误。 我想你的意思是这样的:

all (\x->x) $ zipWith (==) listA listB

第四,(\x->x) 更为人所知的是函数 id

all id $ zipWith (==) listA listB

第五点,正如Matvey指出的那样,all idand是相同的。

and $ zipWith (==) listA listB

第六点,当列表长度不同时,它们会执行不同的操作。在列表上直接使用(==)会得到False,而zipWith会忽略多余的元素。也就是说:

[1,2,3] == [1,2]                   -- False
and $ zipWith (==) [1,2,3] [1,2]   -- True

现在,可能存在你想要第二种行为的情况。但你几乎肯定想要第一种行为。

最后,强调一下,直接在列表上使用(==)即可:

listA == listB

1
我将你的第一句话理解为“首先,Hammar的回答是不正确的,请接受这个答案。” - luqui
7
好的,非常模糊的字母。关闭您键盘的抗锯齿功能 :-) - luqui

11
您可以使用and替换all(\x -> x)

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