H98 Report: semantics of pattern matching

Ross Paterson ross@soi.city.ac.uk
Mon, 21 Jan 2002 17:20:04 +0000


In section 3.17 Pattern Matching, there are some inconsistencies between
the informal and formal semantics:

(1) Section 3.17.2 Informal Semantics of Pattern Matching needs an extra
rule (before rule 2):

	Matching _|_ against the pattern con pat, where con is a
	constructor defined by newtype, is equivalent to matching _|_
	against the pattern pat.

(2) Rule 3 "Matching _|_ against a refutable pattern always diverges" is
untrue, because rules 4(b) and (c) (numeric literals and n+k patterns)
are also applicable to _|_, and it is possible to define the Eq, Ord
and Num classes so that pattern matching is non-strict:

> data Foo = Foo
> instance Eq Foo where _ == _ = True
> instance Ord Foo where _ > _ = False
> instance Show Foo
> instance Num Foo

> f :: Foo -> Int
> f 0 = 20

> g :: Foo -> Int
> g (n+1) = 20		-- Hugs incorrectly requires the Integral class

so f undefined = g undefined = 20.  Other definitions could be hyperstrict,
so _|_/non-_|_ distinction isn't relevant.

I'd suggest changing rule 3 to

	Matching _|_ against a pattern whose outermost component is a
	constructor defined by data always diverges.

deleting rule 4 and promoting the subrules, removing "non-_|_" from (c)
and changing "if x < k" to "otherwise".  You might wish to say it diverges
if x >= k does, but maybe that's too formal.

(3) Section 3.17.3 Formal Semantics of Pattern Matching needs an extra
equation:

	case _|_ of { K x1 ... xn -> e; _ -> e' } = _|_
	where K is a data constructor of arity n

(4) Equation (r) uses let, suggesting the possibility of polymorphism --
I'd suggest changing the rhs to

	if v >= k then case v-k of { x -> e } else e'