Search code examples
pattern-matchingschemedestructuring

Scheme pattern matching - Match cons pair components and the whole cons pair at the same time


How a cons pair components (car and cdr) and the whole cons pair can be pattern matched in scheme using match-lambda? I'm looking for a concise and elegant way of extracting the cons pair components and having a reference to the whole cons pair at the same time.

The question can be split into two questions

  1. How cons pair components (car and cdr) can be pattern matched in scheme?
  2. How the whole pattern matched expression with the matched components can be captured in a single reference using match-lambda? I know that the above can be done using match inside lambda.

I've tried with no luck the below

(match-lambda
  [(car-component . cdr-component) ... use car-component and cdr-component])

Ideally I'm looking for something like

(match-lambda
  [((car-component . cdr-component) as whole-pair) ... use car-component, cdr-component, and whole pair])

Solution

  • If the matcher can match cons pairs at all then you need an and pattern:

    (match-lambda
      [(and whole
            (cons a b))
       ;; whole, a, b bound here
       ...]
      ...)
    

    will work using Racket's match-lambda.

    It looks as though different implementations have different syntaxes for matching conses as opposed to proper lists, and it's not clear to me that, for instance, Guile's can, but they all seem to have and, meaning 'all the patterns must match, binding suitable identifiers'.

    (I'd regard an implementation which doesn't let you match conses as a little unuseful personally, so I hope they all do. But I'm not a Scheme person, really.)