Reputation: 921
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:
x = 1
, y = 2
, r = []
and c = 0
. 2 > 1
so we get in the 1st branch and call countIncreases (2:[]) (0 + 1)
c = 1
so return 1
What am I doing wrong?
Upvotes: 2
Views: 140
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
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
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