リストから多数のテスト関数を自動生成したいと考えています。利点は、リストを変更できること (たとえば、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))))])))
あなたが私に与えることができるガイダンスをありがとう!
PS 合格するはずのいくつかのテストを次に示します。
(define-all/ate? *oxyanion-tests*)
(module+ test
(require rackunit)
(check-true (borate? "B O3"))
(check-true (carbonate? "C O3"))
(check-true (silicate? "Si O4")))