我想從列表中自動生成一堆測試函數。好處是我可以更改列表(例如通過讀取CSV數據表),程序將在下一次程序執行時自動生成不同的測試。球拍宏自動定義列表中的函數
例如,說我試圖找出oxyanions在含有chemical formula的字符串。
我的目錄可能是這樣的:
(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")))
我有理由相信,化學式包含這些oxyanions之一,如果有陽離子,接着氧氣括號內(例如,「(C O3) 「),或者陽離子後面是2個或更多個氧原子(例如」C03「)。請注意,這並不完美,因爲它會漏掉次氯酸鹽陰離子(例如「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")))