Reputation: 21
Im new to haskell and Im writing a function that compares two sequences and reports the length of the prefix they have in common. This is what I have so far but it doesn't work for all cases.
commonLen :: Eq a => [a] -> [a] -> Int
commonLen (x:xs) [] = 0
commonLen (x:xs) (y:ys) | x==y = 1+(commonLen xs ys)
| otherwise = commonLen xs ys
Any ideas where im going wrong? Any help would be appreciated
Upvotes: 1
Views: 247
Reputation: 477065
You should not recurse in case x
is different from y
. In that case we return 0
:
commonLen :: Eq a => [a] -> [a] -> Int
commonLen [] _ = 0
commonLen _ [] = 0
commonLen (x:xs) (y:ys) | x == y = 1 + commonLen xs ys
| otherwise = 0 -- ← return 0
You also can avoid the explicit recursion, and work with:
commonLen :: Eq a => [a] -> [a] -> Int
commonLen xs ys = length (takeWhile id (zipWith (==) xs ys))
here we iterate over both lists concurrently, and compare the elements. We thus make a list of Bool
s that is True
if the elements of the two lists match. Then we use takeWhile
to take elements as long as the item is True
, and we use length
to determine the number of elements in that list. Due to Haskell's laziness, we will never evaluate the entire list if one of the elements differs from the corresponding element in the other list.
Upvotes: 4