我有这样的 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 中做些什么来尽可能地消除这里的缺点?最好使用此模块中的生成器:
  • https://hackage.haskell.org/package/hedgehog-0.5.1/docs/Hedgehog-Gen.html
  • 请您参考如下方法:

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

    最后一点,不要生成一个整数然后将其映射到一个值,而是使用 oneofelement .

     element [MkAnyType TInt, MkAnyType TBool] 
    


    评论关闭
    IT干货网

    微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!