7

我有这样的 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"

但是这种方法对我有几个缺点:

  1. 没有外部类型安全。如果我向数据类型添加另一个构造函数,TType我可能会忘记修复测试,编译器不会对此发出警告。
  2. 编译器不能阻止我写作intToAnyType 1 = MkAnyType TInt
  3. 我不喜欢这个errorInt类型对我来说太宽泛了。让这种模式匹配详尽无遗会很好。

我可以在 Haskell 中做些什么来尽可能地消除这里的缺点?最好使用此模块中的生成器:

4

1 回答 1

4

使用 Template Haskell生成genTType可能是自动维护生成器的最佳选择,因为没有对 GADT 的通用编程支持。

对于最后一点,不要生成整数然后将其映射到一个值,而是使用oneofor element

 element [MkAnyType TInt, MkAnyType TBool]
于 2018-01-13T19:27:13.053 回答