check for exhaustive patterns is broken

Feliks Kluzniak feliks at crt.se
Mon Feb 11 09:30:55 EST 2002


Hello,

I put this one on the SourceForge bug list in November, but there is no
indication that anyone has noticed it.

The problem is that I get a false warning for patterns with guards (see below),
which is a bit of a shame, because these warnings are very useful.

There are workarounds: instead of the final guard (with "k == k'") one can use
a separate catch-all pattern; or, instead of guards, one can use a nested 
"case compare k k'".  I regard both these solutions as less pretty.

Surely, the properties of "<", ">" and "==" are such that the compiler can see
there are no other cases?  

I do realise that similar treatment of general predicates defined by the user
would be hard to implement. ;-)

Regards,
-- Feliks Kluzniak


--------- The incorrect warnings:

ghc --make -odir../ghc -hidir../ghc -Wall -fno-warn-missing-signatures GHCerror.hs
ghc-5.02.2: chasing modules from: GHCerror.hs
Compiling See              ( GHCerror.hs, ../ghc/GHCerror.o )

GHCerror.hs:17: Warning: Pattern match(es) are non-exhaustive
    In the definition of `insert':
	Patterns not matched: _ _ (TREE _ _ _ _)

GHCerror.hs:41: Warning: Pattern match(es) are non-exhaustive
    In a case alternative EMPTY: Patterns not matched: TREE _ _ _ _



--------- The file:

module See
       where



data  Tree key value  =  EMPTY
                      |  TREE key value (Tree key value) (Tree key value)



insert ::  ( Ord key ) =>
             key -> value ->            --  insert this new key and value
             Tree key value ->          --  into this tree
             Maybe (Tree key value)     --  to form (Just new tree ),
                                        --       or Nothing if key is present

insert k v EMPTY  =  Just (TREE k v EMPTY EMPTY)

insert k v (TREE k' v' left right)

    |  k < k'   =  case  insert k v left  of
                     Nothing    -> Nothing
                     Just left' -> Just (TREE k' v' left' right)

    |  k > k'   =  case  insert k v right  of
                     Nothing     -> Nothing
                     Just right' -> Just (TREE k' v' left right')

    |  k == k'  =  Nothing




-- Same with a case expression:

insert' ::  ( Ord key ) =>
              key -> value -> Tree key value -> Maybe (Tree key value)

insert' k v t  =

   case  t  of

       EMPTY  -> Just (TREE k v EMPTY EMPTY)

       (TREE k' v' left right)

           |  k < k'   ->  case  insert' k v left  of
                             Nothing    -> Nothing
                             Just left' -> Just (TREE k' v' left' right)

           |  k > k'   ->  case  insert' k v right  of
                             Nothing     -> Nothing
                             Just right' -> Just (TREE k' v' left right')

           |  k == k'   ->  Nothing




-- Nonsensical, but patterns without guards:

insert'' ::  key -> value -> Tree key value -> Maybe (Tree key value)

insert'' _ _ EMPTY                  =  Nothing

insert'' k v (TREE _ _ left right)  =  Just (TREE k v left right)

-------------------------------------------------------------------------------



More information about the Glasgow-haskell-bugs mailing list