Reputation: 43
I wrote a function that would take a list [a] and would group all equal values into another list - so the output would be something like [[a]]. Now I used ghci with (-W) Warnings enabled, and it seems one of my patterns isn't exhaustive - could you help me find the case my pattern doesn't match yet ? <3
h :: Eq a => [a] -> [[a]]
h [] = []
h (x:xs) = help x xs [x] []
where help :: Eq a => a -> [a] -> [a] -> [a] -> [[a]]
help _ [] s [] = [s] --line 15
help _ [] s n = s : (h n)
help a (y:ys) s n | a == y = help a ys (y:s) n
| a /= y = help a ys s (y:n)
test.hs:15:8: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘help’: Patterns not matched: _ (_:_) _ _
|
15 | help _ [] s [] = [s]
| ^^^^^^^^^^^^^^^^^^^^...
Upvotes: 3
Views: 114
Reputation: 48672
Basically, because it's technically possible that neither of your guards a == y
or a /= y
are true.
Even though it's commonly assumed that Eq
means an equivalence relation, the Haskell Report actually doesn't define any laws for it. In particular, the "custom" x /= y = not (x == y)
can be violated. (And even if it were a law, those still aren't enforced by the compiler.) Consider this:
data BadIdea = BadIdea
instance Eq BadIdea where
_ == _ = False
_ /= _ = False
Although you really shouldn't do that, you can, and then your program would crash since neither case was true.
The easiest way for you to fix this is to replace a /= y
with otherwise
. This is analogous to the fact that you wouldn't write if a == y then ...
and if a /= y then ...
but would rather write if a == y then ... else ...
. Since in practice, no real types have an Eq
instance that's so pathological, this won't really change your program's behavior (and if you did use such a type, it would just consider them unequal instead of crashing).
Upvotes: 4