I have GADT like this one:
data TType a where
TInt :: TType Int
TBool :: TType Bool
I want to have a function like this one:
genTType :: Gen (TType a)
Which can generate random constructor of TType
type. I can do this simply by creating existentially qualified data type like
data AnyType = forall a . MkAnyType (TType a)
then generate random number from 0
to 1
(including) and create AnyType
depending on the integer value. Like this:
intToAnyType :: Int -> AnyType
intToAnyType 0 = MkAnyType TInt
intToAnyType 1 = MkAnyType TBool
intToAnyType _ = error "Impossible happened"
But this approach has couple drawbacks to me:
TType
data type I can forgot to fix tests and compiler won't warn me about this.intToAnyType 1 = MkAnyType TInt
.error
. Int
type is too broad to me. It would be nice to make this pattern-matching exhaustive.What can I do in Haskell to eliminate as much as possible drawbacks here? Preferably using generators from this module:
Generating genTType
with Template Haskell is probably your best bet to automate maintenance of the generators, because there is no generic programming support for GADTs.
For your last point, instead of generating an integer and then mapping it to a value, use oneof
or element
.
element [MkAnyType TInt, MkAnyType TBool]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With