我有这样的 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 中做些什么来尽可能地消除这里的缺点?最好使用此模块中的生成器: