Pattern matching with where free variables can be used more than once

Wouldn't it be great if pattern variables could be used more than once in a pattern? Like so: foo [x,x,_,x] = "The values are the same!" foo _ = "They're not the same!" where this could be rewritten to: foo [x,y,_,z] | x == y && x == z = "The values are the same!" foo _ = "They're not the same!" It seems like a straight-forward translation and there wouldn't be a speed hit for normal patterns because it would only be triggered in compilation where the same free variable appears twice. Implications are: 1. in ``foo [x,y] = ...'', x has type a 1. in ``foo [x,x] = ...'', x has type Eq a => a Was this ever considered? Is it a bad idea for some reason I'm not aware of? On a mildly irrelevant note, I have observed newbies to the language wonder why on earth it's not already like this. Cheers

Christopher,
Wouldn't it be great if pattern variables could be used more than once in a pattern? Like so:
foo [x,x,_,x] = "The values are the same!" foo _ = "They're not the same!"
These are called nonlinear patterns. I think Miranda (a precursor of Haskell, sort of) used to have them. Cheers, Stefan

Am Freitag, 17. Juli 2009 20:38 schrieb Stefan Holdermans:
Christopher,
Wouldn't it be great if pattern variables could be used more than once in a pattern? Like so:
foo [x,x,_,x] = "The values are the same!" foo _ = "They're not the same!"
These are called nonlinear patterns. I think Miranda (a precursor of Haskell, sort of) used to have them.
Yes, Miranda had them. I see the following problem with them: Patterns are about the structure of data. So using the same variable twice in the same pattern should mean that the values that match the variable must have the same structure. This would break data abstraction. For example, matching a pair of sets against the pattern (x,x) would succeed if both sets were represented by the same tree internally, but not succeed if both sets were equal but represented differently. Best wishes, Wolfgang

On Jul 18, 2009, at 6:35 AM, Christopher Done wrote: [non-linear patterns] This kind of matching is provided in Prolog and Erlang. Neither of them lets the user define equality. We find the same issue with n+k patterns (e.g., n+1 as a pattern) l++r patterns (e.g., "prefix"++tail) (x,x) patterns (hidden ==) In each case, the question is "what if the Prelude's version of the explicit or implied function is not in scope?" (For n+k patterns, is the relevant function "+" or is it ">=" and "-"? For l++r patterns, is it "++", or "null", "head", and "tail"?) My preferred answer would be to say "the only functions in scope in a pattern are constructors; these aren't functions, they're syntax, and they always relate to the Prelude." The Haskell' community's preferred answer seems to be "avoid the question, ban the lot of them." It's fair to say that any such pattern _can_ be rewritten to something Haskell can handle; it's also fair to say that the result is often less readable, but that a rewrite may reduce the pain.

Richard O'Keefe wrote:
On Jul 18, 2009, at 6:35 AM, Christopher Done wrote: [non-linear patterns]
This kind of matching is provided in Prolog and Erlang. Neither of them lets the user define equality.
We find the same issue with n+k patterns (e.g., n+1 as a pattern) l++r patterns (e.g., "prefix"++tail) (x,x) patterns (hidden ==)
In each case, the question is "what if the Prelude's version of the explicit or implied function is not in scope?" (For n+k patterns, is the relevant function "+" or is it ">=" and "-"? For l++r patterns, is it "++", or "null", "head", and "tail"?)
My preferred answer would be to say "the only functions in scope in a pattern are constructors; these aren't functions, they're syntax, and they always relate to the Prelude."
The Haskell' community's preferred answer seems to be "avoid the question, ban the lot of them."
It's fair to say that any such pattern _can_ be rewritten to something Haskell can handle; it's also fair to say that the result is often less readable, but that a rewrite may reduce the pain.
Also, there was a big long thread about non-linear patterns a couple months back. The conclusion of which was "yes we could, but it would cause civil war". Some like that kind of sugar, some strongly dislike it, some wonder where it will all end, and some say just go use Curry already :3 -- Live well, ~wren

Well, as I said previously, in reply to Wolfgang, forget the (==) and/or Eq
instance; just use the constructors. You don't need an Eq instance for them.
You have the expression:
foo (a,b)
and the definition:
foo (X,X) = ..
Let's say the predicate for checking that the value of `a' matches X is
Predicate A.
Likewise, for
foo (x,x) = ...
We can use Predicate A to compare `a' and `b', for determining whether the
(x,x) pattern succeeds.
2009/7/18 Richard O'Keefe
On Jul 18, 2009, at 6:35 AM, Christopher Done wrote: [non-linear patterns]
This kind of matching is provided in Prolog and Erlang. Neither of them lets the user define equality.
We find the same issue with n+k patterns (e.g., n+1 as a pattern) l++r patterns (e.g., "prefix"++tail) (x,x) patterns (hidden ==)
In each case, the question is "what if the Prelude's version of the explicit or implied function is not in scope?" (For n+k patterns, is the relevant function "+" or is it ">=" and "-"? For l++r patterns, is it "++", or "null", "head", and "tail"?)
My preferred answer would be to say "the only functions in scope in a pattern are constructors; these aren't functions, they're syntax, and they always relate to the Prelude."
The Haskell' community's preferred answer seems to be "avoid the question, ban the lot of them."
It's fair to say that any such pattern _can_ be rewritten to something Haskell can handle; it's also fair to say that the result is often less readable, but that a rewrite may reduce the pain.
participants (5)
-
Christopher Done
-
Richard O'Keefe
-
Stefan Holdermans
-
Wolfgang Jeltsch
-
wren ng thornton