I have a GADT, like this one:
data TType a where
TInt :: TType Int
TBool :: TType Bool
I want to have a function like this:
genTType :: Gen (TType a)
May generate a random type constructor TType. I can do this simply by creating an existentially qualified data type, e.g.
data AnyType = forall a . MkAnyType (TType a)
then generate a random number from 0to 1(including) and create AnyTypedepending 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 several drawbacks:
- There is no external security. If I add another constructor to the data type
TType, I may forget to fix the tests, and the compiler will not warn me about this. - The compiler cannot stop me from writing
intToAnyType 1 = MkAnyType TInt. error. Int . .
Haskell, ? :