
Simon Peyton-Jones wrote:
| The trouble with those parts is that NOWHERE do they discuss how to | translate a let or where containing more than one binding. If they're | not to be translated via tupling, then how are they to be translated?
Sorry I wasn't clear. Given let { p1 = e1; ... ; pn = en } in e0
(P1) For each pattern pi that is of form !qi = ei, transform it to xi@qi = ei and replace e0 by (xi `seq` e0)
(P2) Now no pattern has a ! at the top. Now apply the existing rules in 3.12 of the Haskell report.
So step (P1) above adds some seqs, and after that it's all just standard Haskell 98.
My summary so far:
Good summary.
1) Bang patterns by themselves are quite decent, well-behaved patterns.
2) Rule (P1) is simple to describe. But the ! in a pattern binding is treated as part of the *binding* rather than part of the *pattern* which is wart-y.
And as a consequence, it is no longer possible to transform a pair of bindings into a binding of a pair. In Haskell 98, p1 = e1 p2 = e2 is always equivalent to (~p1, ~p2) = (e1,e2) and you can make this change *locally*, without consideration of the body of the let in which the bindings appear. With ! bindings (let's use a different name from ! patterns, because they are not the same thing), there's no way to rewrite !p1 = e1 !p2 = e2 as a single tuple binding, because there's nowhere you can put the ! that will have the same effect. Thus we lose a law from the algebra of bindings, which is part of the reason why this is warty. John