Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: check if two lists are equal

Tags:

I want to check if two lists A and B are equal, i.e., 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==b1 and call the function with the remaining lists as and bs. But isn't there an easier and more readable way to do this?

like image 613
mort Avatar asked Dec 01 '11 09:12

mort


2 Answers

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 Eq type class, and there is an Eq instance for lists which looks something like this:

instance Eq a => Eq [a] 

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

like image 160
hammar Avatar answered Sep 19 '22 08:09

hammar


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

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.)

Second, A and B aren't lists: they start with upper case letters, so they cannot be variables. I'm going to call them listA and listB instead.

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:

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

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

all id $ zipWith (==) listA listB 

Fifth, as Matvey points out, all id is the same as and.

and $ zipWith (==) listA listB 

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

[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 
like image 35
dave4420 Avatar answered Sep 21 '22 08:09

dave4420