Search code examples
haskellquickcheckexistential-type

Generating an Existential type with QuickCheck?


I'm struggling with this one - how could QuickCheck generate a value for all types? Maybe it could forge it, and only test types with the context Arbitrary a => a?

I'm just wondering how someone could make an instance of arbitrary for data constructors with an existential type:

data Foo a = Foo a (forall b. (a -> b, b -> a))

Solution

  • It's a bit hard to tell what you're really trying to do, especially since your example type doesn't make a lot of sense. Consider something else:

    newtype WrappedLens s t a b = WrappedLens (forall f . Functor f => (a -> f b) -> s -> f t)
    
    newtype WL = WL (WrappedLens (Int, Int) (Int, Int) Int Int)
    

    Is it possible to make an arbitrary WL? Sure! Just pass fmap explicitly and use the arbitrary function instance. Is it possible to make an arbitrary WL that's a law-abiding lens? Now that is a much taller order.

    I would speculate that the hard thing about making arbitrary values involving higher rank types is not the types so much as the fact that they tend to involve functions in some fashion, and it's hard to constrain arbitrary functions to the ones you actually want to consider.