> There are two issues going on here.
>
> 1. Should pattern variables be permitted in the guard?
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Haskell's reply: yes, but the result is always bottom.

Technically, it's only bottom if the pattern variables are evaluated.
This might seem rather subtle.  After all,

        (x,y) | z > 1 || x < 1 = (2,3)
        z = 2

terminates!   Why not

        (x,y) | z > 1 || x < 1 = (2,3)
        z = 0

>       - you need to evaluate the guard to discover which
>               RHS to bind the pattern to
>       - but you need to choose a particular RHS in order to evaluate
>               the guard

True, but this is quite a weak argument in favour of the status quo.
It applies equally well to the the translations I gave.

I don't see a problem with my first translation, since a RHS will be
evaluated exactly when a bound value is needed in a guard, or the
guard evaluates to True.  That doesn't seem to change the semantics
of normal pattern bindings:

        (x,y) | z > 2 = (2,3)

==      (x,y) = let x1@(x,y) = (2,3) in if z > 2 then x1 else error

=       (x,y) = if z > 2 then (2,3) else error

[by substitution].  Is there a subtlety that I'm missing?

> 2. If the RHS chosen by the first guard to return True does not match
> the pattern, should the next RHS with a valid guard be tried.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> We didn't consider this during the design process.
> [...]
> I'm far from convinced that this is a feature though.

I'm not convinced myself, but I wanted to show that there was a simple
source translation in case someone wanted to pick this up...

Kevin


Reply via email to