Norman Graham says:

        In section 4.4 of the Haskell Report (v1.2), a pattern binding of the form

            p | g1 = e1
              | g2 = e2
               ...
              | gm = em
              where { decls }

        is given the translation

            p = let decls in
                if g1 then e1 else
                if g2 then e2 else
                ...
                if gm then em else error "Unmatched pattern"

        This strikes me as a bit odd: It says that only the guards determine
        which e to bind to p. To my mind, the e's should have some say
        in the matter also. If g1 is True and p = e1 fails to match, then
        I would expect the pattern matching to continue with the match
        '| g2 = e2'.

This seems to be based on the assumption that the guard expressions do not
involve the pattern variables.

OK, lets start with that.

The report says that (p21) "a guard is ... evaluated only after all of the
arguments have been successfully matched..."  and this appears to apply to
pattern bindings even though they do not have "arguments".

Based on this I would have expected the match of p to e1 to have been done
first, then, if it succeeded, the guard g1 to be checked. Now it is quite
reasonable, if either the match or the guard failed, to continue with the
next option.

This is not what is implied by the given translation. It's also a problem to
give a translation based on the alternative semantics. So, did we mean it to
be the way it is, and get the translation wrong?

I can't see anything in the report to limit guards to mention only free
variables, but if pattern variables are used in the guards, big problems
arise with the current translation.

If we put the pattern binding in context so that there is an expression

let p | g1 = e1 ... where {decls} in e

then we have the translation

let p = fix ( \^p -> let {decls} in if g1 then e1 else ...) in e.

Taking an example,

let (x,y) | (x==y) = (1,1)  in x

translates eventually to

let z = fix (\ ^(x,y) -> if x==y then (1,1) else error "..." in
    let x' = case z of (x,y) -> x in
    let y' = case z of (x,y) -> y in x'

and I believe that the required fixed point is undefined.
(I tried various examples in gofer and hbc)

It's quite plausible that this should have the meaning that could be
expressed as "let (x,x) = (1,1) in x" if we had non-linear patterns. The
statement  in the report about the environment of the guard being the
environment of the right-hand-side appears to allow this kind of construct.

On the other hand, a translation of the kind suggested above, would work,
because the matching of (1,1) to (x,y) would be done before the x==y check.

So I think we need a different semantics for pattern bindings to the
translation given in the report. I don't know how to express it, though.

--brian


Reply via email to