Я экспериментирую с формой 'соответствия' Ракета и хотел бы сопоставить последовательности элементов в списке. Каждый предмет будет иметь определенные свойства. Например, если я хотел сопоставить чередующиеся последовательности чисел и строк, соответствующие (примерно) регулярному выражению:
#rx"([0-9]+ \"[a-zA-Z0-9]+\")+"
Код ниже, кажется, делает работу:
(define (match-sequence L)
(let ([n-lst '()] ; Used to collect numbers found.
[s-lst '()]) ; Used to collect strings found.
(define (m-test L)
(match L
[(list-rest (? number? n) (? string? s) ... (? m-test))
(set! n-lst `(,@n-lst ,n))
(set! s-lst `(,@s-lst ,(car s)))
(list (reverse n-lst) (reverse s-lst))]
['()
#t]
[else
#f]))
(m-test L)))
Я понимаю, что #rx и код выше не совсем совпадают с последовательностями, но это просто аналогия.
Это самый лаконичный способ написать это в Ракетке?
Я пробовал шаблоны как:
(list ((? number? n) (? string? s)) ...)
и Ракет не принял это.
Шаблоны типа:
(список (? number? n) (? string? s) ...)
требует, чтобы первый элемент списка соответствовал числовому, а все остальные - строкам.
Я пробовал квазиквотацию и сращивание несколькими способами, но безуспешно.
Должно быть, есть более элегантное образование, но я не могу его найти. Любая помощь будет оценена. Спасибо.