Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More Constructible instances #1

Open
Lysxia opened this issue Feb 15, 2018 · 6 comments
Open

More Constructible instances #1

Lysxia opened this issue Feb 15, 2018 · 6 comments

Comments

@Lysxia
Copy link
Owner

Lysxia commented Feb 15, 2018

  • Types from base and QuickCheck
  • Generic types
@isovector
Copy link

How much work would the generic types be?

@Lysxia
Copy link
Owner Author

Lysxia commented Jun 25, 2020

It seems pretty straightforward to get to a working state, but I have some minor concerns about packaging and the API around Arbitrary.

The main and straightforward part is to define Repr a and fromRepr by induction on the generic representation Rep a, GHC.Generics 101-level recipe, no surprises there.

For the superclass constraints Arbitrary (Repr a) and Show (Repr a) you can pull in generic-random and generic-data, which brings me to the following points:

  1. They are extra dependencies, and they seem heavy enough to put this machinery in (yet) another package.
  2. For Arbitrary I imagine most users would already be content with some default settings, but it also doesn't seem too hard to make available the various knobs of generic-random.

(2) could just be me overthinking. (1) needs some decision to be made, but if you agree with it you can just create another package.

(EDIT: I forgot to mention shrinking, QuickCheck has a generic implementation we can just reuse)

@isovector
Copy link

I think we could entirely offload those instances, right? eg instance Arbitrary a => Arbitrary (K1 _1 a) --- plus some newtype wrappers to not make this an orphan. I'm not sure why you'd need generic-random and generic-data.

@Lysxia
Copy link
Owner Author

Lysxia commented Jun 25, 2020

The problem is with sums, that you don't know with what probability to go left or right. You can set that probability arbitrarily, but by definition that's going to be arbitrary and inflexible.

generic-data would be used to derive Show for a type computed from a generic representation. For example, if you want a Constructible instance for:

data MyType = MyCons (Int -> Int)
  -- No instances

you somehow need to define its Repr:

data ReprMyType = ReprMyCons (Int :-> Int)
  deriving (Show, Arbitrary)

except that with generics you don't have the ability to declare data types, so what do you do?

@isovector
Copy link

Hmm, that seems rather involved. Could you instead Replace (->) (:->) (Rep a) as the Repr, and then use from <$> arbitrary @a + some barbies magic to get the Arbitrary (Repr a) instance? This is essentially how higgledy works.

@Lysxia
Copy link
Owner Author

Lysxia commented Jun 25, 2020

That can work, but it's actually even more involved.

Could you instead Replace (->) (:->) (Rep a) as the Repr

I was imagining something even simpler, mapping Repr to every field (K1) of the Rep, and letting that take care of the substitution recursively.

and then use from <$> arbitrary @a + some barbies magic to get the Arbitrary (Repr a) instance?

It seems the main idea is to somehow make a function a -> Repr a, and then fmap that function over arbitrary; that is essentially what QuickCheck does for Fun. That can be done and added to this library too, but:

  • We'll have to copy QuickCheck's Function class (and many instances) and adapt it to test-fun; that's a much more involved task than deriving Arbitrary (Repr a) directly from the generic structure of Repr a.

  • it's only going to work for types containing at most first-order functions (more precisely, whose domains have decidable equality)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants