如何在Haskell中不侵入模块组织QuickCheck Arbitrary实例
解决QuickCheck拆分测试文件时Arbitrary实例依赖问题
方案一:在TestB中导入TestA模块
既然TestA中已经定义了Arbitrary A的实例,直接在TestB里导入TestA模块,就能让GHC找到该实例:
TestA.hs(明确模块名)
module TestA where import Test.QuickCheck import MyModule (A) instance Arbitrary A where arbitrary = ... -- 你的A类型生成逻辑 prop_A :: A -> Bool prop_A = undefined
TestB.hs
module TestB where import Test.QuickCheck import MyModule (A, B) import TestA -- 导入TestA,获取Arbitrary A实例 instance Arbitrary B where arbitrary = ... -- 此处可以正常使用A的arbitrary prop_B :: B -> Bool prop_B = undefined
这种方式适合测试逻辑本身存在依赖的场景,保持测试模块的职责划分。
方案二:抽离共享Arbitrary实例到独立模块
如果多个测试模块都需要用到这些Arbitrary实例,可以把所有自定义类型的QuickCheck实例单独放到一个模块里,避免模块间的耦合:
TestArbitraryInstances.hs
module TestArbitraryInstances where import Test.QuickCheck import MyModule (A, B) instance Arbitrary A where arbitrary = ... instance Arbitrary B where arbitrary = ... -- 依赖A的实例
TestA.hs
module TestA where import Test.QuickCheck import MyModule (A) import TestArbitraryInstances -- 导入共享实例模块 prop_A :: A -> Bool prop_A = undefined
TestB.hs
module TestB where import Test.QuickCheck import MyModule (B) import TestArbitraryInstances -- 导入共享实例模块 prop_B :: B -> Bool prop_B = undefined
这种方式更适合实例较多、多个测试模块复用的场景,让测试逻辑和实例定义解耦。
注意事项
- 不要在多个模块中重复定义同一个类型的
Arbitrary实例,GHC会报重复实例错误。 - 确保Stack的测试配置(
package.yaml或stack.yaml)包含所有测试模块,避免编译时找不到模块。
内容的提问来源于stack exchange,提问作者dhu
相关产品推荐
相关产品推荐

