MrLoon
MrLoon

Reputation: 921

Missing pattern match in a recursive function

I just started learning Haskell and have a problem writing a basic function.

This function should tell me for how many elements of an array the previous element is bigger than the current one. Here's the code:

countIncreases :: (Ord a, Num b) => [a] -> b -> b
countIncreases [x] c = c
countIncreases (x:y:r) c 
  | y > x = countIncreases (y:r) (c+1) 
  | otherwise = countIncreases (y:r) c

I try to test it with

countIncreases [1,2] 0

I paste all this code in ghci but get the error

Non-exhaustive patterns in function countIncreases

I think however that all patterns needed for that case are matched:

  1. 1st iter.: x = 1, y = 2, r = [] and c = 0. 2 > 1 so we get in the 1st branch and call countIncreases (2:[]) (0 + 1)
  2. 2nd iter.: c = 1 so return 1

What am I doing wrong?

Upvotes: 2

Views: 140

Answers (3)

MrLoon
MrLoon

Reputation: 921

Thank you guys for answering my question. Turns out the root of the problem was something different. Key thing is the fact that I was using ghci and inserting the overloads line by line thinking each line adds an overload to the function definition. Turns out with each line I was overwriting the previous input. So there was always only the last one present in the memory.

From this question I learned how to do multiline input in ghci and following that my function works fine.

Upvotes: 0

radrow
radrow

Reputation: 7139

You forgot to consider the empty list ([]) case:

countIncreases :: (Ord a, Num b) => [a] -> b -> b
countIncreases [x] c = c
countIncreases (x:y:r) c 
  | y > x = countIncreases (y:r) (c+1) 
  | otherwise = countIncreases (y:r) c
countIncreases [] c = c  -- here! 

If you think the function should never be called like that, however, you can throw an error:

countIncreases [] _ = error "countIncrease on empty list!" 

On the other hand, I can't reproduce the error on your test.

Upvotes: 3

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476699

If you run your function, it will not produce an error, if you however compile the code where you turn on the -Wincomplete-patterns, and treat warnings as errors (-Werror), it will error on this.

The reason this happens is because you can not run this function with an empty list. Indeed, if you call it with an empty list, both the [x] and (x:y:r) pattern will fail.

If you count the number of increasing items, then for an empty list, there are no such elements, so you can implement this with:

countIncreases :: (Ord a, Num b) => [a] -> b -> b
countIncreases [] c = c
countIncreases [_] c = c
countIncreases (x:r@(y:_)) c 
  | y > x = countIncreases r (c+1) 
  | otherwise = countIncreases r c

Upvotes: 3

Related Questions