Skip to content

GHC needs to be more careful about pattern match order

The language report specifies pattern match order to be sequential, left-to-right, out-in, top-down. It explicitly allows for different implementations, as long as the differences are not observable and certain rules remain valid. One such rule is:

    case e of {p1->e1;p2->e2} = 
    case e of {p1->e1;_->case e of {p2->e2;_->error "No match"}}

GHC invalidates this rule:

    newtype N = N Int deriving (Show,Eq)
    
    instance Num N where
      fromInteger 0 = error "0"
      fromInteger 1 = N 0
      fromInteger _ = N 1
    
    f x = case x of
            1 -> False
            0 -> True
    
    g x = case x of
            1 -> False
            _ -> case x of
                  0 -> True
                  _ -> error "No match"
    
    main = do
      print $ g (N 0)
      print $ f (N 0)

    -- ghc
    $ ghc -w -e main PMOrderSpec.hs
    False
    <interactive>: 0

    -- hugs
    Main> main
    False
    False

The same effect can be achieved via Data.String.IsString (see attached test case).

See also:

Trac metadata
Trac field Value
Version 6.11
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information