Generic random generators
Go to file
2023-03-14 02:05:56 +01:00
.github/workflows Drop support for GHC 8.4 2023-03-14 02:05:56 +01:00
examples Drop support for GHC 7 2021-05-16 00:07:27 -04:00
src/Generic Remove useless TypeInType 2023-03-14 02:05:56 +01:00
test test: Add use of AndShrinking 2021-07-09 16:47:06 -04:00
CHANGELOG.md CHANGELOG: Typo 2023-03-14 02:05:56 +01:00
generic-random.cabal Drop support for GHC 8.4 2023-03-14 02:05:56 +01:00
LICENSE Initial commit 2016-04-06 23:34:02 +02:00
README.md README: Update ci badge 2022-05-08 18:33:11 -04:00
Setup.hs Initial commit 2016-04-06 23:34:02 +02:00
stack.yaml ci: Bump stack resolver 2021-07-09 17:06:51 -04:00

Generic random generators Hackage Build Status

Generic random generators to implement Arbitrary instances for QuickCheck

Automating the arbitrary boilerplate also ensures that when a type changes to have more or fewer constructors, then the generator either fixes itself to generate that new case (when using the uniform distribution) or causes a compilation error so you remember to fix it (when using an explicit distribution).

This package also offers a simple (optional) strategy to ensure termination for recursive types: make Test.QuickCheck.Gen's size parameter decrease at every recursive call; when it reaches zero, sample directly from a trivially terminating generator given explicitly (genericArbitraryRec and withBaseCase) or implicitly (genericArbitrary').

Example

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics (Generic)
import Test.QuickCheck
import Generic.Random

data Tree a = Leaf | Node (Tree a) a (Tree a)
  deriving (Show, Generic)

instance Arbitrary a => Arbitrary (Tree a) where
  arbitrary = genericArbitraryRec uniform `withBaseCase` return Leaf

-- Equivalent to
-- > arbitrary =
-- >   sized $ \n ->
-- >     if n == 0 then
-- >       return Leaf
-- >     else
-- >       oneof
-- >         [ return Leaf
-- >         , resize (n `div` 3) $
-- >             Node <$> arbitrary <*> arbitrary <*> arbitrary
-- >         ]

main :: IO ()
main = sample (arbitrary :: Gen (Tree ()))