Non-exhaustive patterns in function
Solution 1
It looks like you're missing the case where there's a one element list:
countLongest' n max (y:ys)
| ... etc. ...
| otherwise = ....
Here's a contrived example similar to yours:
f [] = 3 -- matches an empty list
f (a:b:bs) = 4 -- matches a list with at least two elements
Examples:
Prelude> :load myfile.hs
[1 of 1] Compiling Main ( myfile.hs, interpreted )
Ok, modules loaded: Main.
*Main> f [3]
*** Exception: myfile.hs:(3,0)-(4,13): Non-exhaustive patterns in function f
*Main> f []
3
*Main> f [1,2,3,4,5]
4
*Main>
So it succeeds with 0 and 2 elements in the list, but fails when there's exactly one element.
Note that this behavior is not unique to lists. Here's an example using Maybe
:
g :: Maybe x -> x
g (Just x) = x
Examples:
*Main> g (Just 4)
4
*Main> g Nothing
*** Exception: myfile.hs:6:0-13: Non-exhaustive patterns in function g
This happened because there's two constructors for Maybe
, Just <something>
and Nothing
. We didn't provide a case for Nothing
, so when we passed that into g
, it didn't work!
Check out this question and its answers for information on getting a little help from the compiler. I followed the advice of the first answer, and when I loaded my examples, this is what happened:
prompt$ ghci -fwarn-incomplete-patterns
Prelude> :load myfile.hs
[1 of 1] Compiling Main ( myfile.hs, interpreted )
myfile.hs:3:0:
Warning: Pattern match(es) are non-exhaustive
In the definition of `f': Patterns not matched: [_]
myfile.hs:6:0:
Warning: Pattern match(es) are non-exhaustive
In the definition of `g': Patterns not matched: Nothing
Ok, modules loaded: Main.
Cool! The compiler is pretty smart!
Solution 2
The problem is that you need to match for if there is 1 element left in the recursion, for example:
countLongest' n max (y:ys)
Because the first one matches if there are 2 or more elements left and the last only matches if there is no element left.
kaz
Updated on July 09, 2022Comments
-
kaz almost 2 years
I've got a problem with this code, it should count the longest substring of the same letter in a string, but there is an error:
*** Exception: test.hs:(15,0)-(21,17): Non-exhaustive patterns in function countLongest'
I know that is the wrong types problem, but i dont know where is the error, or how to find or debug it
countLongest :: (Eq a) => [a] -> Int countLongest' :: (Eq a) => Int -> Int -> [a] -> Int countLongest a = countLongest' 0 0 a countLongest' n max (y:x:ys) | y == x = countLongest' (n+1) max (x:ys) | n > max = countLongest' 0 (n) (x:ys) | otherwise = countLongest' 0 (max) (x:ys) countLongest' n max [] | n > max = n | otherwise = max