Kostas Thanasis
Kostas Thanasis

Reputation: 378

Compare elements from two lists

I’m doing my homework in Haskell and I got to a point where I need to compare two lists element by element and count how many elements are the same and in the same place: the first element of the first list with the first element of the second list, etc..

Here’s what I have:

compare :: [Int]->[Int]->Int
compare [a] [b]= if head a == head b then 1 + compare (tail a tail b) else 0 + compare (tail a tail b)

compare [] [b] = 0

I know in advance that they will both be lists with 8 Ints as elements.

Upvotes: 1

Views: 6122

Answers (2)

Ry-
Ry-

Reputation: 224862

The problems with your code are:

  • The patterns: you’re defining compare [a] [b], but you want a and b to be lists because you’re using them with head and tail. Just define compare a b instead.

  • The order of the patterns: the first match wins, so your compare [] b = 0 should come first.

  • compare (tail a tail b) should be giving two arguments to compare, not three arguments to tail. compare (tail a) (tail b).

All told:

compare :: [Int] -> [Int] -> Int
compare [] _ = 0
compare a b =
    if head a == head b then
        1 + compare (tail a) (tail b)
    else
        compare (tail a) (tail b)

And although it probably isn’t suitable for homework, it might be fun to know that you can write this by getting a list of booleans indicating whether certain positions are equal, filtering them to only true values, and getting the resulting length:

compare a = length . filter id . zipWith (==) a

-- this works too
compare a = sum . fromEnum . zipWith (==) a

Upvotes: 3

gabesoft
gabesoft

Reputation: 1228

You could zip the two lists and then compare on the resulting tuples lists map (uncurry compare) $ zip l1 l2 assuming you have two lists l1 and l2

and to count all places where they have the same elements length $ filter (== EQ) $ map (uncurry compare) $ zip l1 l2

Upvotes: 2

Related Questions