Racket Macro для автоматического определения функций по заданному списку

Я хочу автоматически сгенерировать кучу тестовых функций из списка. Преимущество в том, что я могу изменить список (например, прочитав таблицу данных CSV), и программа автоматически сгенерирует различные тесты при следующем выполнении программы.

Например, скажите, что я пытаюсь идентифицироватьоксианионы в строке, содержащейхимическая формула.

Мой список может быть что-то вроде:

(define *oxyanion-tests*
  ;           name         cation
  (list (list "aluminate"  "Al")
        (list "borate"     "B")
        (list "gallate"    "Ga")
        (list "germanate"  "Ge")
        (list "phosphate"  "P")
        (list "sulfate"    "S")
        (list "silicate"   "Si")
        (list "titanate"   "Ti")
        (list "vanadate"   "V")
        (list "stannate"   "Sn")
        (list "carbonate"  "C")
        (list "molybdate"  "Mo")
        (list "tungstate"  "W")))

Я достаточно уверен, что химическая формула содержит один из этихоксианионы если в скобках есть катион, за которым следует кислород (например, «(C O3)»), или если за катионом следуют 2 или более кислорода (например, «C O3»). Обратите внимание, что это не идеально, так как он пропустит гипохлоритовые анионы (например, «Cl O»), но этого достаточно для моего применения.

(define ((*ate? elem) s-formula)
  (or (regexp-match? (regexp (string-append "\\(" elem "[0-9.]* O[0-9.]*\\)")) s-formula)
      (regexp-match? (regexp (string-append "(^| )" elem "[0-9.]* O[2-9][0-9.]*")) s-formula)))

Я думаю, что мне нужен макрос для этого, но я не совсем понимаю, как они работают, читая документацию. Я прошу здесь, чтобы у меня был хороший пример, чтобы посмотреть на него, который сразу же полезен для меня.

Вот как я думаю, что макрос должен выглядеть, но он не работает, и у меня нет ментальной модели, чтобы выяснить, как это исправить.

(require (for-syntax racket))
(define-syntax-rule (define-all/ate? oxyanion-tests)
  (for ([test oxyanion-tests])
    (match test
      [(list name cation) (syntax->datum (syntax (define ((string->symbol (string-append name "?")) s-formula)
                                    ((*ate? cation) s-formula))))])))

Спасибо за любое руководство, которое вы можете дать мне!

Постскриптум Вот несколько тестов, которые должны пройти:

(define-all/ate? *oxyanion-tests*)
(module+ test
  (require rackunit)
  (check-true (borate? "B O3"))
  (check-true (carbonate? "C O3"))
  (check-true (silicate? "Si O4")))

Ответы на вопрос(1)

Ваш ответ на вопрос