我想从列表中自动生成一堆测试函数。好处是我可以更改列表(例如通过读取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")))