Non exhaustive patterns in Haskell recursion

109 Views Asked by At

I'm trying to write a function which gives me the distance between every district in my list. The function distance gives me the distance between two districts as an Int from a set array, and I want to run through the whole list to sum up the distance between every district and its follower in the list.

But I'm getting the

Non-exhaustive patterns

error message. What have I overlooked? The function distance is working as it should.

lengthr :: [district] -> Int
lengthr [] = 0
lengthr (a:b:as) = (distance a b) + lengthr (b:as) 
2

There are 2 best solutions below

0
On

As you mentioned in your own answer, you were missing the case of a single element.

A more general solution is to include a catch-all pattern _ after all of the specific cases you want to handle.

lengthr:: [district] -> Int
lengthr (a:b:as) = (distance a b) + lengthr (b:as)
lengthr _ = 0

This a more conventional way to handle default situations.

In situations where the result is contained in a Monad that has error semantics (e.g., Either e and Maybe), you can make the default case an error instead of potentially ignoring a bug.

lengthr:: [district] -> Either String Int
lengthr (a:b:as) = do
  next <- lengthr (b:as)
  Right $ (distance a b) + next
lengthr [_] = Right 0
lengthr _ = Left "empty list"
0
On

I added the line lengthr [a] = 0 to my code, to cover up the case of only one element left, and now the code works as intended!