nick8325 / quickcheck

Automatic testing of Haskell programs.
Other
706 stars 119 forks source link

Make Negative's arbitrary instance work like that of Positive #377

Closed Wheatwizard closed 3 months ago

Wheatwizard commented 3 months ago

Currently Negative and Positive have arbitrary instances which are inconsistent with each other.

Positive generates an arbitrary, takes its absolute value, and checks that it is greater than 0; while Negative just checks the value is less than zero.

One would expect that the instance would behave like:

arbitrary = fmap (Negative . negate . getPositive) arbitrary

however, because of the differences in the implementations, it does not.

This MR would make the two have consistent behavior by adjusting Negative's arbitrary instance to have parity with Positive's instance.

The alternative could be done, adjusting Positive's instance to match that of Negative, but I chose to adjust it this way since the definition of arbitrary for Positive rejects fewer values.

MaximilianAlgehed commented 3 months ago

I like it!

The only shortcoming I see is that this will crash in more cases where either abs or negate aren't defined than the old instance would. I don't think this shortcoming is particularly severe given that you probably shouldn't be using Negative at a type that doesn't implement negate and abs.