-Woverlapping-patterns warns on wrong patterns for Int
GHC-8.0 introduced a new warning on redundant pattern matches in case
clauses.
But there is something strange.
$ cat RedundantCase.hs
main :: IO ()
main = do
case 0::Int of
0 -> putStrLn "A"
1 -> putStrLn "B"
_ -> putStrLn "C"
case 0::Int of
0 -> putStrLn "A"
1 -> putStrLn "B"
2 -> putStrLn "C"
case 0::Integer of
0 -> putStrLn "A"
1 -> putStrLn "B"
_ -> putStrLn "C"
case 0::Integer of
0 -> putStrLn "A"
1 -> putStrLn "B"
2 -> putStrLn "C"
case 0::Integer of
1 -> putStrLn "B"
2 -> putStrLn "C"
let dummy :: Integer
dummy = 0
case dummy of
0 -> putStrLn "A"
1 -> putStrLn "B"
_ -> putStrLn "C"
case "foo" of
"foo" -> putStrLn "A"
"bar" -> putStrLn "B"
"baz" -> putStrLn "C"
if True
then putStrLn "X"
else putStrLn "Y"
$ ghc-8.2.2 -Wall RedundantCase.hs
[1 of 1] Compiling Main ( RedundantCase.hs, RedundantCase.o )
RedundantCase.hs:4:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 0 -> ...
|
4 | 0 -> putStrLn "A"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:5:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 1 -> ...
|
5 | 1 -> putStrLn "B"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:8:4: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In a case alternative: Patterns not matched: 0
|
8 | case 0::Int of
| ^^^^^^^^^^^^^^...
RedundantCase.hs:9:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 0 -> ...
|
9 | 0 -> putStrLn "A"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:10:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 1 -> ...
|
10 | 1 -> putStrLn "B"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:11:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 2 -> ...
|
11 | 2 -> putStrLn "C"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:15:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 1 -> ...
|
15 | 1 -> putStrLn "B"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:16:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: _ -> ...
|
16 | _ -> putStrLn "C"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:20:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 1 -> ...
|
20 | 1 -> putStrLn "B"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:21:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 2 -> ...
|
21 | 2 -> putStrLn "C"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:23:4: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In a case alternative: Patterns not matched: 0
|
23 | case 0::Integer of
| ^^^^^^^^^^^^^^^^^^...
RedundantCase.hs:24:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 1 -> ...
|
24 | 1 -> putStrLn "B"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:25:7: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: 2 -> ...
|
25 | 2 -> putStrLn "C"
| ^^^^^^^^^^^^^^^^^
RedundantCase.hs:34:4: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In a case alternative:
Patterns not matched:
[]
(p:_) where p is not one of {'b', 'f'}
['b']
('b':p:_) where p is not one of {'a'}
...
|
34 | case "foo" of
| ^^^^^^^^^^^^^...
Linking RedundantCase ...
In the first case it warns about the wrong patterns,
in the second case it warns about all patterns and a non-exhaustive pattern list.
In the following three cases using Integer
the warnings seem to be correct.
The next case shows that I can suppress the warning if I hide the constant nature of the case selector a bit.
Then a case on a String
- GHC does not seem to try to detect redundant pattern matches
but falls back to a general test on exhaustive pattern lists.
Finally, in a constant case
on Bool
I can avoid the warning using a plain if-then-else
.
Now I wonder what the purpose of the warning is at all.
First I thought that it wants to warn me, that the patterns overlap,
i.e. pattern _
contains the already handled case 0
.
This does not seem to be the purpose of the warning - and such overlapping patterns are pretty common, aren't they?
Second thought: GHC wants to warn me about redundant patterns in the presence of a constant case selector.
But then, it does so with varying degrees of success: For Integer
it works, but not for Int
or String
.
Is it really only about constant case selectors?
Then, not only some pattern matches are redundant but the whole case
clause is redundant.
Then again, can't we assume that the programmer wrote such a case
clause by intend?
At least, this is how I use a case
clause with constant selector: as a type-safe way to out-comment alternative implementations.
Thus my question: Where is this warning useful?
Trac metadata
Trac field | Value |
---|---|
Version | 8.2.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |