I'm not sure this is possible with only using `match` patterns. A
combination of the `list-rest` and `app` patterns as well as the `in-slice`
procedure from `racket/sequence` should do the trick, though:
#lang racket
(require racket/match)
(define (collect-optional-vals x)
(for/list ([y (in-slice 4 x)])
y))
(match '(req-a req-b name1 age1 first1 last1 name2 age2 first2 last2)
[(list-rest req-a req-b (app collect-optional-vals optional-vals))
(list req-a req-b optional-vals)])
On Mon, May 4, 2020 at 7:16 PM David Storrs <[email protected]> wrote:
> I'm trying to write a parser for a CSV file with optional columns.
> Simplified version: There are 2 mandatory columns, after which there can
> be 0+ 4-column groups describing a person. Each group has the same column
> headers.
>
> ; legal column arrangements:
> RequiredA RequiredB
> RequiredA RequiredB Name Age First Last
> RequiredA RequiredB Name Age First Last Name Age First Last
>
>
> ; illegal: if an optional group is present, it must have all 4 columns
> RequiredA RequiredB Name Age First Last Name
>
> I thought I could do this straightforwardly with `match`, but I'm wrong.
> Can someone point me to the way to write such a match clause?
>
>
> Various failed attempts:
> (list reqA reqB (opt1 opt2 opt3 opt4) ...) ; syntax error. matching
> clauses do not do grouping like this
> (list reqA reqB (list opt1 opt2 opt3 opt4) ...) ; didn't expect this to
> work since it would specify an embedded list. I was right.
>
> This one surprised me:
> (match row
> [(list required1 required2 (and opt1 opt2 opt3 opt4) ...)
> (list opt1 opt2 opt3 opt4)])
>
> This distributes the ... over the four items inside the 'and' clause such
> that each of the 'optionalN' identifiers matches all remaining elements.
> '(("Name" "Age" "First" "Last")
> ("Name" "Age" "First" "Last")
> ("Name" "Age" "First" "Last")
> ("Name" "Age" "First" "Last"))
>
> In hindsight it makes sense -- the 'and' causes it to match the element
> across all four patterns. They all match because they are identifiers and
> therefore match anything. Then the '...' causes it to do that for all
> remaining elements, generating lists into each of the identifiers because
> that's what '...' does.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CAE8gKocCPSgVQG_aMSC%3DQJAmAtxvmCN8vqpwsankKnCJZAOotw%40mail.gmail.com
> <https://groups.google.com/d/msgid/racket-users/CAE8gKocCPSgVQG_aMSC%3DQJAmAtxvmCN8vqpwsankKnCJZAOotw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/racket-users/CACehHmA6Xo87zckX4N8JbXDJVaVob6cp3Dk%2B%3DD3DG80DDgonyQ%40mail.gmail.com.