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)

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