out-commented code vs. case with redundant pattern matches

Occasionally I have multiple implementations of the same task and want to choose one quickly but statically. I do not want to out-comment unused branches because they shall still be type checked. So far I used this scheme: case 0::Int of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C" With ghc-8.0.2 and ghc-8.2.2 I get these warnings: RedundantCase.hs:4:7: warning: [-Woverlapping-patterns] Pattern match is redundant In a case alternative: 0 -> ... RedundantCase.hs:5:7: warning: [-Woverlapping-patterns] Pattern match is redundant In a case alternative: 1 -> ... I thought that "redundant" means that the first two cases overlap with '_'. But if I replace '_' by '2' I get not only the non-exhaustive patterns warning but an additional redundancy warning on pattern '2'. Is there a nice way to tell GHC that the unused branches are intended, without generally disabling overlapping patterns warning? I mean, this one does not provoke any warnings: if True then putStrLn "X" else putStrLn "Y" but is limited to two branches.

Hi Henning, Thus quoth Henning Thielemann on Wed Nov 29 2017 at 11:04 (+0100):
Occasionally I have multiple implementations of the same task and want to choose one quickly but statically. I do not want to out-comment unused branches because they shall still be type checked. So far I used this scheme:
case 0::Int of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C"
Maybe you can factor out the implementations of different branches into separate functions, like in: case 0 :: Int of 0 -> putStrLn "A" 1 -> handleOne1 where handleOne1 :: Int -> IO () handleOne1 = putStrLn "B" handleOne1 :: Int -> IO () handleOne2 = putStrLn "C" This should keep the typechecking.
With ghc-8.0.2 and ghc-8.2.2 I get these warnings:
RedundantCase.hs:4:7: warning: [-Woverlapping-patterns] Pattern match is redundant In a case alternative: 0 -> ...
RedundantCase.hs:5:7: warning: [-Woverlapping-patterns] Pattern match is redundant In a case alternative: 1 -> ...
I thought that "redundant" means that the first two cases overlap with '_'. But if I replace '_' by '2' I get not only the non-exhaustive patterns warning but an additional redundancy warning on pattern '2'.
Is there a nice way to tell GHC that the unused branches are intended, without generally disabling overlapping patterns warning?
To me, you are creating overlapping patterns in the case statements, so having unused branches and _not_ having warnings about them kind of breaks the point of this type of warning (personal opinion). Now, depending on the localisation of alternative branches, you may want to use per-file preprocessor directives to disable the warning. -- Sergiu
I mean, this one does not provoke any warnings:
if True then putStrLn "X" else putStrLn "Y"
but is limited to two branches. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Wed, 29 Nov 2017, Sergiu Ivanov wrote:
Hi Henning,
Maybe you can factor out the implementations of different branches into separate functions, like in:
case 0 :: Int of 0 -> putStrLn "A" 1 -> handleOne1 where handleOne1 :: Int -> IO () handleOne1 = putStrLn "B"
handleOne1 :: Int -> IO () handleOne2 = putStrLn "C"
I had something similar in mind and found it too complicated. I could also omit 'case' completely, and directly call handleOne1 and prefix unused handleOne's with an underscore. Maybe it is the best I can do for now.
To me, you are creating overlapping patterns in the case statements, so having unused branches and _not_ having warnings about them kind of breaks the point of this type of warning (personal opinion).
Not quite. We can silence "unused" warnings for variables by prepending an underscore. Something similar might work for case patterns.

On Wed, 29 Nov 2017, Sergiu Ivanov wrote:
Thus quoth Henning Thielemann on Wed Nov 29 2017 at 11:04 (+0100):
Occasionally I have multiple implementations of the same task and want to choose one quickly but statically. I do not want to out-comment unused branches because they shall still be type checked. So far I used this scheme:
case 0::Int of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C"
I have filed a GHC ticket: https://ghc.haskell.org/trac/ghc/ticket/14546

I thought that "redundant" means that the first two cases overlap with '_'. But if I replace '_' by '2' I get not only the non-exhaustive patterns warning but an additional redundancy warning on pattern '2'.
I think it's a bug of the PM check instead: it doesn't correctly detect redundant Int alternatives ("1" and "_" in your example). Could you report it as a bug? Note that it works as expected with Integer: "case 0 :: Integer of" reports "1 ->..." and "_ -> ..." as redundant. A solution to avoid the warning is: let choosePut = 0 :: Int case choosePut of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C" -Sylvain On 29/11/2017 11:04, Henning Thielemann wrote:
Occasionally I have multiple implementations of the same task and want to choose one quickly but statically. I do not want to out-comment unused branches because they shall still be type checked. So far I used this scheme:
case 0::Int of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C"
With ghc-8.0.2 and ghc-8.2.2 I get these warnings:
RedundantCase.hs:4:7: warning: [-Woverlapping-patterns] Pattern match is redundant In a case alternative: 0 -> ...
RedundantCase.hs:5:7: warning: [-Woverlapping-patterns] Pattern match is redundant In a case alternative: 1 -> ...
I thought that "redundant" means that the first two cases overlap with '_'. But if I replace '_' by '2' I get not only the non-exhaustive patterns warning but an additional redundancy warning on pattern '2'.
Is there a nice way to tell GHC that the unused branches are intended, without generally disabling overlapping patterns warning?
I mean, this one does not provoke any warnings:
if True then putStrLn "X" else putStrLn "Y"
but is limited to two branches. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Hi, Am Mittwoch, den 29.11.2017, 11:04 +0100 schrieb Henning Thielemann:
Occasionally I have multiple implementations of the same task and want to choose one quickly but statically. I do not want to out-comment unused branches because they shall still be type checked. So far I used this scheme:
case 0::Int of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C"
You can write case id (0::Int) of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C" instead.
I mean, this one does not provoke any warnings:
if True then putStrLn "X" else putStrLn "Y"
but is limited to two branches.
It looks like a but that it warns for Int, but not for Bool… freel free to report that (https://ghc.haskell.org/trac/ghc/wiki/ReportABug). Joachim -- Joachim “nomeata” Breitner mail@joachim-breitner.de https://www.joachim-breitner.de/
participants (4)
-
Henning Thielemann
-
Joachim Breitner
-
Sergiu Ivanov
-
Sylvain Henry