nick8325 / quickcheck

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

Add `shrinkBoundedEnum` function. #350

Closed jonathanknowles closed 1 year ago

jonathanknowles commented 1 year ago

This PR adds a new function shrinkBoundedEnum, which should resolve issue https://github.com/nick8325/quickcheck/issues/343.

The shrinkBoundedEnum function provides a counterpart to the pre-existing arbitraryBoundedEnum function. Together, they can be used to define a complete Arbitrary instance for a bounded enumeration data type.

For example, let's say we have the following (admittedly contrived) type:

data MyEnum
    = E00 | E01 | E02 | E03 | E04 | E05 | E06 | E07 | E08 | E09
    | E10 | E11 | E12 | E13 | E14 | E15 | E16 | E17 | E18 | E19
    | E20 | E21 | E22 | E23 | E24 | E25 | E26 | E27 | E28 | E29
    | E30 | E31 | E32 | E33 | E34 | E35 | E36 | E37 | E38 | E39
    | E40 | E41 | E42 | E43 | E44 | E45 | E46 | E47 | E48 | E49
    | E50 | E51 | E52 | E53 | E54 | E55 | E56 | E57 | E58 | E59
    | E60 | E61 | E62 | E63 | E64 | E65 | E66 | E67 | E68 | E69
    | E70 | E71 | E72 | E73 | E74 | E75 | E76 | E77 | E78 | E79
    | E80 | E81 | E82 | E83 | E84 | E85 | E86 | E87 | E88 | E89
    | E90 | E91 | E92 | E93 | E94 | E95 | E96 | E97 | E98 | E99
    deriving (Bounded, Enum, Eq, Ord, Show)

We can then define the following Arbitrary instance:

instance Arbitrary MyEnum where
    arbitrary = arbitraryBoundedEnum
    shrink = shrinkBoundedEnum

Since shrinkBoundedEnum reuses shrinkIntegral internally, we get similar shrinking behaviour: values earlier in the shrink list are shrunk more aggressively, followed by the usual exponential back-off:

>>> shrinkBoundedEnum E99
[E00,E50,E75,E87,E93,E96,E98]
>>> shrinkBoundedEnum E49
[E00,E25,E37,E43,E46,E48]
>>> shrinkBoundedEnum E00
[]
jonathanknowles commented 1 year ago

Hi @nick8325

Just wondering if you think this function would be useful? If you like the idea, but you'd like me to make revisions to it -- let me know, would be happy to do so.

All the best! Jonathan

nick8325 commented 1 year ago

It looks good! Thanks for the patch!

jonathanknowles commented 1 year ago

It looks good! Thanks for the patch!

You're welcome!