Linearity Requirement for Patterns
brian boutel
brian@boutel.co.nz
Mon, 19 Mar 2001 23:04:50 +1200
Michael Hanus wrote:
>
> Brian Boutel wrote:
> > In any case, the same effect can be obtained using guards, where the
> > extra power of expression syntax solves the problem. Instead of
> > f x x = e1
> > f (illegal pattern) = e2
> > ...
> >
> > you can write the single equation
> >
> > f x y | x == y = e1
> > | x /= y = e2
>
> It depends on the meaning of pattern matching wrt. non-linear
> patterns. The standard notion (e.g., term rewriting) matches
> a pattern by finding a substitution for the pattern variables
> so that the instantiated pattern is identical to the function
> call. In this case, it can also match partially defined
> functions in contrast to your transformation. For instance,
> consider the definitions
>
> g z = 1 + g z
> f x x = 0
>
> Then a call like (f (g 0) (g 0)) is reducible to 0
> (wrt. standard notion of pattern matching using the instantiation
> {x |-> (g 0)}) whereas it is undefined if we transform this definition to
>
> f x y | x==y = 0
>
> (which requires the evaluation of both arguments).
> Thus, I would say that non-linear patterns gives you
> extra power.
>
I don't think so.
Haskell is not a term rewriting system, and lacks the notion of
syntactic identity of expressions that would be required for your
scheme. If non-linear patterns were to be added, I do not think this
would change, and there would be no increase in power.
Moreover, sometimes your scheme would be less powerful. Consider
f x x = 0
f x y = f x (y+1)
and call f (factorial 5) (15 * 8)
This will be undefined unless you evaluate both arguments before
matching - which you say above that you wish to avoid. And if you do not
eveluate both, you lose referential transparency, for if I substutute
the argument values, and write f 120 120, you would then match the first
case and get 0 instead of bottom.
--brian