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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8339264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:44:55  来源:igfitidea点击:

Haskell: check if two lists are equal

listhaskell

提问by mort

I want to check if two lists Aand Bare equal, i.e., a1 == b1, a2 == b2,...

我要检查,如果两个列表AB相等,即a1 == b1, a2 == b2,...

I have a working solution:

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

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

Another idea is to do it recursively: a:as, b:bs; check if a1==b1and call the function with the remaining lists asand bs. But isn't there an easier and more readable way to do this?

另一个想法是递归地做到这一点:a:as, b:bs; 检查是否a1==b1并使用剩余的列表as和调用该函数bs。但是,难道没有一种更简单、更易读的方法来做到这一点吗?

回答by hammar

You can just use ==on them directly.

您可以==直接在它们上使用。

> [1, 2, 3] == [1, 2, 3]
True
> [1, 2, 3] == [1, 2]
False

This is because ==is part of the Eqtype class, and there is an Eqinstance for lists which looks something like this:

这是因为==Eq类型类的一部分,并且有一个Eq列表实例,它看起来像这样:

instance Eq a => Eq [a]

This means that lists instantiate Eqas long as the element type also instantiates Eq, which is the case for all types defined in the standard Prelude except functions and IOactions.

这意味着列表实例化Eq只要元素类型也实例化Eq,标准 Prelude 中定义的所有类型都是这种情况,函数和IO动作除外。

回答by dave4420

First, hammar's answer is correct, so accept his answer please. (Edit: Which you have done, thank you.)

首先,hammar 的回答是正确的,所以请接受他的回答。(编辑:您已经完成了,谢谢。)

listA == listB

(I'm going to nitpick on small details in your question, mostly for the benefit of future beginners who find this page on Google.)

(我将挑剔您问题中的小细节,主要是为了将来在 Google 上找到此页面的初学者的利益。)

Second, Aand Baren't lists: they start with upper case letters, so they cannot be variables. I'm going to call them listAand listBinstead.

其次,AB不是列表:他们开始用大写字母,所以不能为变量。我要打电话给他们listAlistB而不是。

Third, there is a typo in your working solution: the $should be before the zipWith, not after. The way it appears in your question results in a compile error. I think you meant this:

第三,您的工作解决方案中有一个错字:$应该在 之前zipWith,而不是之后。它在您的问题中出现的方式会导致编译错误。我想你的意思是:

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

Fourth, (\x->x)is better known as the function id.

第四,(\x->x)更广为人知的功能id

all id $ zipWith (==) listA listB

Fifth, as Matvey points out, all idis the same as and.

第五,正如 Matvey 指出的,all idand.

and $ zipWith (==) listA listB

Sixth, these do different things when the lists have different lengths. Using (==)directly on lists will result in False, whereas zipWithwill ignore the excess elements. That is:

第六,当列表的长度不同时,它们会做不同的事情。(==)直接在列表上使用将导致False,而zipWith将忽略多余的元素。那是:

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

Now, there are probably situations when you want the second behaviour. But you almost certainly want the first behaviour.

现在,可能会出现您想要第二种行为的情况。但是你几乎肯定想要第一个行为。

Finally, to emphasise, just use (==)directly on the lists:

最后,要强调的是,只需(==)直接在列表上使用:

listA == listB

回答by Matvey Aksenov

You can replace all (\x -> x)with and.

您可以替换all (\x -> x)and.