
On 26/01/06, Simon Peyton-Jones
I agree that if (n+k) patterns go, then so should k patterns. Both are overloaded, and that's the root of their complexity.
I'm not so sure about that. I don't use (n+k) patterns at all, but I do get fairly regular use out of k patterns. (n+k) patterns can seem like an odd special case in everything but Nat, but k patterns are often the nicest way to handle base cases, and save you from writing awkward-looking guards. Sure, they're not usually appropriate for floating point computations, but for integral and rational types, they work very well. (even if you can't pattern match against fractions) One possibility is that k patterns could be generalised to arbitrary members of Eq, rather than just being used for numbers. We could even make variables bound in the parameter list available. So for a simplistic example, one could write: f :: (Eq a, Num a) => a -> a -> a f x x = x -- if the two parameters match, give their common value f _ _ = 0 -- otherwise give 0. The first 'x' would pattern match as usual, and the second would compare for equality with the first. We'd have to work out the exact syntax for them -- essentially, it would just involve detecting an arbitrary expression which was not a pattern. There's some context sensitivity there with the option of referring to previously bound variables though. I'm not sure how often this would be used, and perhaps it's more trouble than it's worth, but at least it leaves no further room for generalisation, which makes the feature seem somewhat natural. Even without previous-variable-binding, it subsumes all pattern matching on literals, so it would take some thought to determine if it really makes things more complicated or not.
Personally I think ~ patterns are great, and we are now talking about ! patterns, a kind of dual to ~ patterns. So at least I think we should un-couple the two discussions.
I think so too. Removing ~ patterns seems like a fairly poor idea to me. Sure, they're not very much explicitly used (though everyone uses them implicitly in pattern bindings), but when you want them, they can be fairly important. I think perhaps we just need better coverage of ~ in the tutorials. Now that I think about it, I rather like the idea of ! patterns as well. They make ~ patterns seem more natural by contrast. Strictness can on occasion be just as important as laziness, and this notation makes it more convenient to obtain in simple cases. How to get a similarly pretty notation for more structured strictness annotations is a bit of a concern. I wonder whether some of the Control.Parallel.Strategies library should be more strategically located? :) - Cale