> 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