On Wed, Dec 30, 2020 at 2:24 PM David Storrs <
david....@gmail.com> wrote:
>
> First off, is there a way to make ... in a pattern match non-greedily? i.e., match as *few* elements as possible instead of as many?
As far as I know, no. However, if your first example is really
illustrative of what you're trying to do, you could just use a `cons`
pattern instead of a `list` pattern:
(match (list '(a b c) '(d e c))
[(list (cons _ xs) (cons _ ys))
#:when (equal? xs ys)
'ok]
[else 'nope])
=> 'nope
And that makes a nice segue into your second question:
> Second, is there a way to make one pattern refer to an earlier pattern in the same match clause?
If we're limiting this to variable patterns, then yes. The
documentation says: "If an id is used multiple times within a pattern,
the corresponding matches must be the same according to
(match-equality-test), except that instances of an id in different or
and not sub-patterns are independent." So, assuming that
`(match-equality-test)` is `equal?` -- which is the default -- the
above could also be written as:
(match (list '(a b c) '(d e c))
[(list (cons _ xs) (cons _ xs))
'ok]
[else 'nope])
Similarly, your second example could be written as:
(match '(a b c c d)
[(list _ ... x x _ ...)
'ok]
[else 'nope])
However, I have seen some issues with this feature (using the same var
pattern multiple times to get an equality restriction). Most recently:
https://github.com/racket/racket/issues/3425
- Jon