我想对我库中的各种类型进行许多类似的测试。
为了简化事情,假设我有许多矢量类型实现Num
类,并且我想生成相同的 QuickCheck 属性检查prop_absNorm x y = abs x + abs y >= abs (x+y)
,该检查将适用于库中的所有类型。
我使用 TH 生成这样的属性:
$(writeTests
(\t ->
[d| prop_absNorm :: $(t) -> $(t) -> Bool
prop_absNorm x y = abs x + abs y >= abs (x+y)
|])
)
我生成测试的函数具有以下签名:
writeTests :: (TypeQ -> Q [Dec]) -> Q [Dec]
此函数通过查找我的向量类的所有实例VectorMath (n::Nat) t
(以及同时查找 的实例Num
)reify ''VectorMath
并相应地生成所有 prop 函数。
-ddump-splices
显示如下内容:
prop_absNormIntX4 :: Vector 4 Int -> Vector 4 Int -> Bool
prop_absNormIntX4 x y = abs x + abs y >= abs (x+y)
prop_absNormCIntX4 :: Vector 4 CInt -> Vector 4 CInt -> Bool
prop_absNormCIntX4 x y = abs x + abs y >= abs (x+y)
...
prop_absNormFloatX4 :: Vector 4 Float -> Vector 4 Float -> Bool
prop_absNormFloatX4 x y = abs x + abs y >= abs (x+y)
prop_absNormFloatX3 :: Vector 3 Float -> Vector 3 Float -> Bool
prop_absNormFloatX3 x y = abs x + abs y >= abs (x+y)
问题是检查了所有手动编写的属性,但没有检查生成的属性。
注意 1:我在同一个文件中生成了和未生成的属性(即 TH 表达式$(..)
与其他道具在同一个文件中)。
注 2:用于创建 prop 函数的类型列表是可变的 - 我想VectorMath
稍后添加其他实例,因此它们会自动添加到测试列表中。
我认为问题在于 HTF(可能也使用 TH)解析原始文件,而不是生成代码的文件 - 但我不明白为什么会发生这种情况。
所以我的问题是:如何解决这个问题?如果无法使用 TH 生成的道具,那么是否可以对各种类型进行 QuickCheck 测试(即,将它们替换为prop_absNorm :: Vector 4 a -> Vector 4 a -> Bool
)?
另一种选择可能是进一步使用 TH 手动将测试条目添加到 htf_Main,但我还没有弄清楚如何做到这一点;它看起来不像是一个干净的解决方案。