我有这样的 GADT:
data TType a where
TInt :: TType Int
TBool :: TType Bool
我想要一个这样的功能:
genTType :: Gen (TType a)
可以生成
TType
的随机构造函数类型。我可以简单地通过创建存在限定的数据类型来做到这一点
data AnyType = forall a . MkAnyType (TType a)
然后从
0
生成随机数至
1
(包括)和创建
AnyType
取决于整数值。像这样:
intToAnyType :: Int -> AnyType
intToAnyType 0 = MkAnyType TInt
intToAnyType 1 = MkAnyType TBool
intToAnyType _ = error "Impossible happened"
但是这种方法对我有几个缺点:
TType
添加另一个构造函数我可以忘记修复测试的数据类型,编译器不会就此发出警告。 intToAnyType 1 = MkAnyType TInt
. error
. Int
类型对我来说太宽泛了。让这种模式匹配详尽无遗会很好。 我可以在 Haskell 中做些什么来尽可能地消除这里的缺点?最好使用此模块中的生成器:
请您参考如下方法:
生成genTType
使用 Template Haskell 可能是您自动维护生成器的最佳选择,因为没有对 GADT 的通用编程支持。
最后一点,不要生成一个整数然后将其映射到一个值,而是使用 oneof
或 element
.
element [MkAnyType TInt, MkAnyType TBool]