
Hi Yitzchak Gale wrote:
I would like to suggest a correction to ticket #56, "Pattern Guards".
It is easy to show that every expression written using pattern guards can also be written in Haskell 98 in a way that is essentially equivalent in simplicity. (Proof below.)
Whether or not your conclusion is correct, your candidate proof is incomplete.
funlhs | qual11, qual12, ..., qual1n = exp1 | qual21, qual22, ..., qual2n = exp2 ...
we translate the function binding into Haskell 98 as:
funlhs = runExit $ do maybeExit $ do {qual11'; qual12'; ...; qual1n'; return (exp1)} maybeExit $ do {qual21'; qual22'; ...; qual2n'; return (exp2)} ...
This translation does not appear to address programs with multiple left-hand sides, exploiting fall-through from match (hence guard) failure, eg varVal :: String -> [(String, String)] -> String varVal x locals | Just y <- lookup x locals = y varVal "X" xys = "42" varVal _ _ = error "var not found" Haskell 98 provides no means to inspect the value of an intermediate computation (something other than an argument or component thereof) without committing to one right-hand side. I think that's rather unfortunate, because it loses the visual tabulation of the possibilities and priorities. I'm not a big fan of pattern guards, though, because they only give you one shot at matching the intermediate result. Some means to do 'case e' on the left would be nice. Maybe gcd x y | compare x y -> LT = gcd x (y - x) GT = gcd (x - y) y gcd x _ = x or some such. I wish I could think of a better example without too much context, but such a thing escapes me for the moment. In general, I think it's good to collocate on the left as much as possible of a function's scrutineering. Stringing out ifs and cases makes it harder to see what's going on. All the best Conor