Fantastic.  Thanks, Michael.

On Mon, May 4, 2020 at 10:39 PM Michael MacLeod <[email protected]>
wrote:

> 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/CAE8gKocyrT%3DAUAzvkiWs6AxP118LrxX89CFNOzHf%2BJKj4pdGLQ%40mail.gmail.com.

Reply via email to