I'm observing an interesting behavior when using pattern matching with pattern guards and all warnings turned on
{-# OPTIONS_GHC -Wall #-}
module Mood where
data Mood = Happy
          | Indifferent
          | Sad
          deriving Show
flipMood :: Mood -> Mood
flipMood Happy       = Sad
flipMood Indifferent = Indifferent
flipMood Sad         = Happy
flipMood' :: Mood -> Mood
flipMood' mood
  | Happy       <- mood = Sad
  | Indifferent <- mood = Indifferent
  | Sad         <- mood = Happy
Even though flipMood and flipMood' are pretty much doing the same thing I get the following error message:
Mood.hs:15:1: Warning:
    Pattern match(es) are non-exhaustive
    In an equation for ‘flipMood'’: Patterns not matched: _
Ok, modules loaded: Mood.
and therefore need to add a catch all case like
| otherwise = mood
to satisfy the exhaustiveness checker.
Core seems to be just fine with these two functions behaving the same:
flipMood =
  \ ds_dTh ->
    case ds_dTh of _ {
      Happy -> Sad;
      Indifferent -> Indifferent;
      Sad -> Happy
    }
flipMood' = flipMood
With optimizations turned off I get the following Core output which seems to explain this behavior:
flipMood' =
  \ mood_axV ->
    case mood_axV of wild_X9 {
      __DEFAULT ->
        case wild_X9 of _ {
          Indifferent -> Indifferent;
          Sad -> Happy
        };
      Happy -> Sad
    }
Why is it behaving this way? Am I missing something?
Kind regards, raichoo
There is a long 10 year old ticket about that. Basically: exhaustive checking in ghc is waiting for the hero.
Added: The issue was closed today. I just checked, the code doesn't produce non-exhaustive warning any more. Hopefully it will be part of ghc-8.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With