Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning that pattern guard is non-exhaustive even though it is

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

like image 602
raichoo Avatar asked Feb 11 '15 12:02

raichoo


1 Answers

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.

like image 90
Yuras Avatar answered Nov 18 '22 19:11

Yuras