From 8f34b9330214d6ba265bc7c5db892571ffebdd10 Mon Sep 17 00:00:00 2001 From: Alexey Kuleshevich Date: Sun, 25 Jul 2021 22:20:16 +0300 Subject: [PATCH 1/3] Add StatefulGen instance for Gen --- src/Test/QuickCheck.hs | 1 + src/Test/QuickCheck/Gen.hs | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/Test/QuickCheck.hs b/src/Test/QuickCheck.hs index 710872e5..259c144f 100644 --- a/src/Test/QuickCheck.hs +++ b/src/Test/QuickCheck.hs @@ -128,6 +128,7 @@ module Test.QuickCheck -- * The 'Gen' monad: combinators for building random generators , Gen + , QC(..) -- ** Generator combinators , choose , chooseInt diff --git a/src/Test/QuickCheck/Gen.hs b/src/Test/QuickCheck/Gen.hs index de8ce323..d618d464 100644 --- a/src/Test/QuickCheck/Gen.hs +++ b/src/Test/QuickCheck/Gen.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE MultiParamTypeClasses #-} #ifndef NO_ST_MONAD {-# LANGUAGE Rank2Types #-} #endif @@ -53,6 +54,9 @@ import GHC.Stack #define WITHCALLSTACK(ty) ty #endif +#ifndef OLD_RANDOM +import System.Random.Stateful +#endif -------------------------------------------------------------------------- -- ** Generator type @@ -102,6 +106,15 @@ instance MonadFix Gen where let a = unGen (f a) r n in a +#ifndef OLD_RANDOM +data QC = QC + +instance StatefulGen QC Gen where + uniformWord32 QC = MkGen (\r _n -> runStateGen_ r uniformWord32) + uniformWord64 QC = MkGen (\r _n -> runStateGen_ r uniformWord64) + uniformShortByteString k QC = + MkGen (\r _n -> runStateGen_ r (uniformShortByteString k)) +#endif -------------------------------------------------------------------------- -- ** Primitive generator combinators From 49fce9efe819022675d7b7e933fac0f0c47c7338 Mon Sep 17 00:00:00 2001 From: Alexey Kuleshevich Date: Sun, 25 Jul 2021 22:42:07 +0300 Subject: [PATCH 2/3] Forgot some CPP --- src/Test/QuickCheck.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Test/QuickCheck.hs b/src/Test/QuickCheck.hs index 259c144f..9a256358 100644 --- a/src/Test/QuickCheck.hs +++ b/src/Test/QuickCheck.hs @@ -128,7 +128,9 @@ module Test.QuickCheck -- * The 'Gen' monad: combinators for building random generators , Gen +#ifndef OLD_RANDOM , QC(..) +#endif -- ** Generator combinators , choose , chooseInt From 1763a642fd6b94d91da1f0192995e5c6344b69ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joosep=20J=C3=A4=C3=A4ger?= Date: Thu, 15 Jan 2026 14:02:37 +0200 Subject: [PATCH 3/3] Added uniformByteArrayM --- src/Test/QuickCheck/Gen.hs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Test/QuickCheck/Gen.hs b/src/Test/QuickCheck/Gen.hs index d618d464..d0e9ae46 100644 --- a/src/Test/QuickCheck/Gen.hs +++ b/src/Test/QuickCheck/Gen.hs @@ -107,14 +107,33 @@ instance MonadFix Gen where in a #ifndef OLD_RANDOM +-- | A monadic adapter that can be passed to stateful generators to make them +-- use @Gen@ as the generator monad. +-- +-- The stateful generator interface can be used as follows +-- > -- 1. Define a stateful generator +-- > myGen :: StatefulGen g m => g -> m (Int, String) +-- > myGen g = do +-- > l <- uniformRM (0, 5) g +-- > s <- replicateM l (uniformM g) +-- > pure (l, s) +-- > +-- > -- 2. Pass QC to the stateful generator to turn it into a QuickCheck generator +-- > myQCGen :: Gen (Int, String) +-- > myQCGen = myGen QC data QC = QC instance StatefulGen QC Gen where uniformWord32 QC = MkGen (\r _n -> runStateGen_ r uniformWord32) uniformWord64 QC = MkGen (\r _n -> runStateGen_ r uniformWord64) +#if MIN_VERSION_random(1,3,0) + uniformByteArrayM pinned sz QC = + MkGen (\r _n -> runStateGen_ r (uniformByteArrayM pinned sz)) +#else uniformShortByteString k QC = MkGen (\r _n -> runStateGen_ r (uniformShortByteString k)) #endif +#endif -------------------------------------------------------------------------- -- ** Primitive generator combinators