Skip to content

Commit

Permalink
Add function shrinkBoundedEnum to Test.QuickCheck.Extra.
Browse files Browse the repository at this point in the history
Though the `QuickCheck` library provides a handy `arbitraryBoundedEnum`
function, it currently doesn't provide a `shrinkBoundedEnum`
counterpart. Users have asked for a function like this here:

nick8325/quickcheck#343

This commit adds our own version, for now. Perhaps, later on, we can
submit a PR to the `QuickCheck` repository to add this function, and
delete our own version.
  • Loading branch information
jonathanknowles committed Jan 17, 2023
1 parent 5da79b0 commit 9f6c83b
Showing 1 changed file with 31 additions and 0 deletions.
31 changes: 31 additions & 0 deletions lib/test-utils/src/Test/QuickCheck/Extra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module Test.QuickCheck.Extra

-- * Shrinking
, liftShrinker
, shrinkBoundedEnum
, shrinkInterleaved
, shrinkMapWith
, groundRobinShrink
Expand Down Expand Up @@ -207,6 +208,36 @@ genSized2With f genA genB = uncurry f <$> genSized2 genA genB
interleaveRoundRobin :: [[a]] -> [a]
interleaveRoundRobin = concat . L.transpose

-- | Shrinks a 'Bounded' 'Enum' value.
--
-- Example:
--
-- @
-- data MyEnum = A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7
-- deriving (Bounded, Enum, Eq, Ord, Show)
-- @
--
-- >>> shrinkBoundedEnum A7
-- [A0,A4,A6]
--
-- >>> shrinkBoundedEnum A4
-- [A0,A2,A3]
--
-- >>> shrinkBoundedEnum A0
-- []
--
-- See 'arbitraryBoundedEnum'.
--
shrinkBoundedEnum :: forall a. (Eq a, Enum a, Bounded a) => a -> [a]
shrinkBoundedEnum a
| a == minBound =
[]
| otherwise =
toEnum <$> filter (>= minBoundInt) (shrinkIntegral $ fromEnum a)
where
minBoundInt :: Int
minBoundInt = fromEnum (minBound @a)

-- | Shrink the given pair in interleaved fashion.
--
-- Successive shrinks of the left and right hand sides are interleaved in the
Expand Down

0 comments on commit 9f6c83b

Please sign in to comment.