Safe Haskell | None |
---|---|
Language | Haskell98 |
- type Gen = GenT Identity
- newtype GenT m a = GenT {}
- class Monad m => MonadGen m where
- lift :: MonadGen m => Gen a -> m a
- shrink :: MonadGen m => (a -> [a]) -> m a -> m a
- prune :: MonadGen m => m a -> m a
- small :: MonadGen m => m a -> m a
- scale :: MonadGen m => (Size -> Size) -> m a -> m a
- resize :: MonadGen m => Size -> m a -> m a
- sized :: MonadGen m => (Size -> m a) -> m a
- integral :: (MonadGen m, Integral a) => Range a -> m a
- integral_ :: (MonadGen m, Integral a) => Range a -> m a
- int :: MonadGen m => Range Int -> m Int
- int8 :: MonadGen m => Range Int8 -> m Int8
- int16 :: MonadGen m => Range Int16 -> m Int16
- int32 :: MonadGen m => Range Int32 -> m Int32
- int64 :: MonadGen m => Range Int64 -> m Int64
- word :: MonadGen m => Range Word -> m Word
- word8 :: MonadGen m => Range Word8 -> m Word8
- word16 :: MonadGen m => Range Word16 -> m Word16
- word32 :: MonadGen m => Range Word32 -> m Word32
- word64 :: MonadGen m => Range Word64 -> m Word64
- realFloat :: (MonadGen m, RealFloat a) => Range a -> m a
- realFrac_ :: (MonadGen m, RealFrac a) => Range a -> m a
- float :: MonadGen m => Range Float -> m Float
- double :: MonadGen m => Range Double -> m Double
- enum :: (MonadGen m, Enum a) => a -> a -> m a
- enumBounded :: (MonadGen m, Enum a, Bounded a) => m a
- bool :: MonadGen m => m Bool
- bool_ :: MonadGen m => m Bool
- binit :: MonadGen m => m Char
- octit :: MonadGen m => m Char
- digit :: MonadGen m => m Char
- hexit :: MonadGen m => m Char
- lower :: MonadGen m => m Char
- upper :: MonadGen m => m Char
- alpha :: MonadGen m => m Char
- alphaNum :: MonadGen m => m Char
- ascii :: MonadGen m => m Char
- latin1 :: MonadGen m => m Char
- unicode :: MonadGen m => m Char
- unicodeAll :: MonadGen m => m Char
- string :: MonadGen m => Range Int -> m Char -> m String
- text :: MonadGen m => Range Int -> m Char -> m Text
- utf8 :: MonadGen m => Range Int -> m Char -> m ByteString
- bytes :: MonadGen m => Range Int -> m ByteString
- constant :: MonadGen m => a -> m a
- element :: MonadGen m => [a] -> m a
- choice :: MonadGen m => [m a] -> m a
- frequency :: MonadGen m => [(Int, m a)] -> m a
- recursive :: MonadGen m => ([m a] -> m a) -> [m a] -> [m a] -> m a
- discard :: MonadGen m => m a
- ensure :: MonadGen m => (a -> Bool) -> m a -> m a
- filter :: MonadGen m => (a -> Bool) -> m a -> m a
- just :: MonadGen m => m (Maybe a) -> m a
- maybe :: MonadGen m => m a -> m (Maybe a)
- list :: MonadGen m => Range Int -> m a -> m [a]
- seq :: MonadGen m => Range Int -> m a -> m (Seq a)
- nonEmpty :: MonadGen m => Range Int -> m a -> m (NonEmpty a)
- set :: (MonadGen m, Ord a) => Range Int -> m a -> m (Set a)
- map :: (MonadGen m, Ord k) => Range Int -> m (k, v) -> m (Map k v)
- freeze :: MonadGen m => m a -> m (a, m a)
- subterm :: MonadGen m => m a -> (a -> a) -> m a
- subtermM :: MonadGen m => m a -> (a -> m a) -> m a
- subterm2 :: MonadGen m => m a -> m a -> (a -> a -> a) -> m a
- subtermM2 :: MonadGen m => m a -> m a -> (a -> a -> m a) -> m a
- subterm3 :: MonadGen m => m a -> m a -> m a -> (a -> a -> a -> a) -> m a
- subtermM3 :: MonadGen m => m a -> m a -> m a -> (a -> a -> a -> m a) -> m a
- subsequence :: MonadGen m => [a] -> m [a]
- shuffle :: MonadGen m => [a] -> m [a]
- sample :: MonadIO m => Gen a -> m a
- print :: (MonadIO m, Show a) => Gen a -> m ()
- printTree :: (MonadIO m, Show a) => Gen a -> m ()
- printWith :: (MonadIO m, Show a) => Size -> Seed -> Gen a -> m ()
- printTreeWith :: (MonadIO m, Show a) => Size -> Seed -> Gen a -> m ()
- runGenT :: Size -> Seed -> GenT m a -> Tree (MaybeT m) a
- mapGenT :: (Tree (MaybeT m) a -> Tree (MaybeT n) b) -> GenT m a -> GenT n b
- generate :: MonadGen m => (Size -> Seed -> a) -> m a
- liftTree :: Tree (MaybeT m) a -> GenT m a
- runDiscardEffect :: Monad m => Tree (MaybeT m) a -> Tree m (Maybe a)
- golden :: Size -> Size
- atLeast :: Int -> [a] -> Bool
- isSurrogate :: Char -> Bool
- data Vec n a where
- data Nat
- subtermMVec :: MonadGen m => Vec n (m a) -> (Vec n a -> m a) -> m a
- renderNodes :: (Monad m, Show a) => Size -> Seed -> Gen a -> Tree m String
Transformer
Monad transformer which can generate random values of a
.
MMonad GenT Source # | |
MonadTrans GenT Source # | |
Distributive GenT Source # | |
MonadBase b m => MonadBase b (GenT m) Source # | |
MonadError e m => MonadError e (GenT m) Source # | |
MonadReader r m => MonadReader r (GenT m) Source # | |
MonadState s m => MonadState s (GenT m) Source # | |
MonadWriter w m => MonadWriter w (GenT m) Source # | |
Monad m => Monad (GenT m) Source # | |
Functor m => Functor (GenT m) Source # | |
Monad m => Applicative (GenT m) Source # | |
MonadIO m => MonadIO (GenT m) Source # | |
Monad m => Alternative (GenT m) Source # | |
Monad m => MonadPlus (GenT m) Source # | |
MonadCatch m => MonadCatch (GenT m) Source # | |
MonadThrow m => MonadThrow (GenT m) Source # | |
PrimMonad m => PrimMonad (GenT m) Source # | |
MonadResource m => MonadResource (GenT m) Source # | |
Monad m => MonadGen (GenT m) Source # | |
MFunctor * GenT Source # | |
type Transformer t GenT m Source # | |
type PrimState (GenT m) Source # | |
class Monad m => MonadGen m where Source #
Class of monads which can generate input data for tests.
The functions on this class can, and should, be used without their Gen
suffix by importing Hedgehog.Gen qualified.
liftGen :: Gen a -> m a Source #
See Gen.
lift
shrinkGen :: (a -> [a]) -> m a -> m a Source #
See Gen.
shrink
pruneGen :: m a -> m a Source #
See Gen.
prune
scaleGen :: (Size -> Size) -> m a -> m a Source #
See Gen.
scale
freezeGen :: m a -> m (a, m a) Source #
See Gen.
freeze
MonadGen m => MonadGen (MaybeT m) Source # | |
Monad m => MonadGen (GenT m) Source # | |
(MonadGen m, Monoid w) => MonadGen (WriterT w m) Source # | |
MonadGen m => MonadGen (StateT s m) Source # | |
MonadGen m => MonadGen (ExceptT x m) Source # | |
MonadGen m => MonadGen (IdentityT * m) Source # | |
MonadGen m => MonadGen (StateT s m) Source # | |
(MonadGen m, Monoid w) => MonadGen (WriterT w m) Source # | |
MonadGen m => MonadGen (ReaderT * r m) Source # | |
(MonadGen m, Monoid w) => MonadGen (RWST r w s m) Source # | |
(MonadGen m, Monoid w) => MonadGen (RWST r w s m) Source # | |
Combinators
Shrinking
shrink :: MonadGen m => (a -> [a]) -> m a -> m a Source #
Apply a shrinking function to a generator.
This will give the generator additional shrinking options, while keeping the existing shrinks intact.
Size
scale :: MonadGen m => (Size -> Size) -> m a -> m a Source #
Adjust the size parameter by transforming it with the given function.
resize :: MonadGen m => Size -> m a -> m a Source #
Override the size parameter. Returns a generator which uses the given size instead of the runtime-size parameter.
sized :: MonadGen m => (Size -> m a) -> m a Source #
Construct a generator that depends on the size parameter.
Integral
integral :: (MonadGen m, Integral a) => Range a -> m a Source #
Generates a random integral number in the given [inclusive,inclusive]
range.
When the generator tries to shrink, it will shrink towards the
origin
of the specified Range
.
For example, the following generator will produce a number between 1970
and 2100
, but will shrink towards 2000
:
integral (Range.constantFrom
2000 1970 2100) ::Gen
Int
Some sample outputs from this generator might look like:
=== Outcome === 1973 === Shrinks === 2000 1987 1980 1976 1974
=== Outcome === 2061 === Shrinks === 2000 2031 2046 2054 2058 2060
integral_ :: (MonadGen m, Integral a) => Range a -> m a Source #
Generates a random integral number in the [inclusive,inclusive] range.
This generator does not shrink.
int :: MonadGen m => Range Int -> m Int Source #
Generates a random machine integer in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
int8 :: MonadGen m => Range Int8 -> m Int8 Source #
Generates a random 8-bit integer in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
int16 :: MonadGen m => Range Int16 -> m Int16 Source #
Generates a random 16-bit integer in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
int32 :: MonadGen m => Range Int32 -> m Int32 Source #
Generates a random 32-bit integer in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
int64 :: MonadGen m => Range Int64 -> m Int64 Source #
Generates a random 64-bit integer in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
word :: MonadGen m => Range Word -> m Word Source #
Generates a random machine word in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
word8 :: MonadGen m => Range Word8 -> m Word8 Source #
Generates a random byte in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
word16 :: MonadGen m => Range Word16 -> m Word16 Source #
Generates a random 16-bit word in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
word32 :: MonadGen m => Range Word32 -> m Word32 Source #
Generates a random 32-bit word in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
word64 :: MonadGen m => Range Word64 -> m Word64 Source #
Generates a random 64-bit word in the given [inclusive,inclusive]
range.
This is a specialization of integral
, offered for convenience.
Floating-point
realFloat :: (MonadGen m, RealFloat a) => Range a -> m a Source #
Generates a random floating-point number in the [inclusive,exclusive)
range.
This generator works the same as integral
, but for floating point numbers.
realFrac_ :: (MonadGen m, RealFrac a) => Range a -> m a Source #
Generates a random fractional number in the [inclusive,exclusive) range.
This generator does not shrink.
float :: MonadGen m => Range Float -> m Float Source #
Generates a random floating-point number in the [inclusive,exclusive)
range.
This is a specialization of realFloat
, offered for convenience.
double :: MonadGen m => Range Double -> m Double Source #
Generates a random floating-point number in the [inclusive,exclusive)
range.
This is a specialization of realFloat
, offered for convenience.
Enumeration
bool :: MonadGen m => m Bool Source #
Generates a random boolean.
This generator shrinks to False
.
This is a specialization of enumBounded
, offered for convenience.
Characters
alphaNum :: MonadGen m => m Char Source #
Generates an ASCII letter or digit: 'a'..'z', 'A'..'Z', '0'..'9'
unicode :: MonadGen m => m Char Source #
Generates a Unicode character, excluding invalid standalone surrogates:
'\0'..'\1114111' (excluding '\55296'..'\57343')
unicodeAll :: MonadGen m => m Char Source #
Generates a Unicode character, including invalid standalone surrogates:
'\0'..'\1114111'
Strings
text :: MonadGen m => Range Int -> m Char -> m Text Source #
Generates a string using Range
to determine the length.
utf8 :: MonadGen m => Range Int -> m Char -> m ByteString Source #
Generates a UTF-8 encoded string, using Range
to determine the length.
bytes :: MonadGen m => Range Int -> m ByteString Source #
Generates a random ByteString
, using Range
to determine the
length.
Choice
element :: MonadGen m => [a] -> m a Source #
Randomly selects one of the elements in the list.
This generator shrinks towards the first element in the list.
The input list must be non-empty.
choice :: MonadGen m => [m a] -> m a Source #
Randomly selects one of the generators in the list.
This generator shrinks towards the first generator in the list.
The input list must be non-empty.
frequency :: MonadGen m => [(Int, m a)] -> m a Source #
Uses a weighted distribution to randomly select one of the generators in the list.
This generator shrinks towards the first generator in the list.
The input list must be non-empty.
recursive :: MonadGen m => ([m a] -> m a) -> [m a] -> [m a] -> m a Source #
Modifies combinators which choose from a list of generators, like choice
or frequency
, so that they can be used in recursive scenarios.
This combinator modifies its target to select one of the generators in
either the non-recursive or the recursive list. When a selection is made
from the recursive list, the Size
is halved. When the Size
gets to one
or less, selections are no longer made from the recursive list, this
ensures termination.
A good example of where this might be useful is abstract syntax trees:
data Expr = Var String | Lam String Expr | App Expr Expr -- Assuming we have a name generator genName ::MonadGen
m => m String -- We can write a generator for expressions genExpr ::MonadGen
m => m Expr genExpr = Gen.recursive
Gen.choice
[ -- non-recursive generators Var<$>
genName ] [ -- recursive generators Gen.subtermM
genExpr (x -> Lam<$>
genName<*>
pure x) , Gen.subterm2
genExpr genExpr App ]
If we wrote the above example using only choice
, it is likely that it
would fail to terminate. This is because for every call to genExpr
,
there is a 2 in 3 chance that we will recurse again.
Conditional
ensure :: MonadGen m => (a -> Bool) -> m a -> m a Source #
Discards the generator if the generated value does not satisfy the predicate.
filter :: MonadGen m => (a -> Bool) -> m a -> m a Source #
Generates a value that satisfies a predicate.
This is essentially:
filter p gen =mfilter
p gen<|>
filter p gen
It differs from the above in that we keep some state to avoid looping forever. If we trigger these limits then the whole generator is discarded.
Collections
list :: MonadGen m => Range Int -> m a -> m [a] Source #
Generates a list using a Range
to determine the length.
seq :: MonadGen m => Range Int -> m a -> m (Seq a) Source #
Generates a seq using a Range
to determine the length.
nonEmpty :: MonadGen m => Range Int -> m a -> m (NonEmpty a) Source #
Generates a non-empty list using a Range
to determine the length.
set :: (MonadGen m, Ord a) => Range Int -> m a -> m (Set a) Source #
Generates a set using a Range
to determine the length.
This may fail to generate anything if the element generator cannot produce a large enough number of unique items to satify the required set size.
map :: (MonadGen m, Ord k) => Range Int -> m (k, v) -> m (Map k v) Source #
Generates a map using a Range
to determine the length.
This may fail to generate anything if the keys produced by the generator do not account for a large enough number of unique items to satify the required map size.
Subterms
freeze :: MonadGen m => m a -> m (a, m a) Source #
Freeze the size and seed used by a generator, so we can inspect the value which it will produce.
This is used for implementing list
and subtermMVec
. It allows us to
shrink the list itself before trying to shrink the values inside the list.
subterm :: MonadGen m => m a -> (a -> a) -> m a Source #
Constructs a generator from a sub-term generator.
Shrinks to the sub-term if possible.
subtermM :: MonadGen m => m a -> (a -> m a) -> m a Source #
Constructs a generator from a sub-term generator.
Shrinks to the sub-term if possible.
subterm2 :: MonadGen m => m a -> m a -> (a -> a -> a) -> m a Source #
Constructs a generator from two sub-term generators.
Shrinks to one of the sub-terms if possible.
subtermM2 :: MonadGen m => m a -> m a -> (a -> a -> m a) -> m a Source #
Constructs a generator from two sub-term generators.
Shrinks to one of the sub-terms if possible.
subterm3 :: MonadGen m => m a -> m a -> m a -> (a -> a -> a -> a) -> m a Source #
Constructs a generator from three sub-term generators.
Shrinks to one of the sub-terms if possible.
subtermM3 :: MonadGen m => m a -> m a -> m a -> (a -> a -> a -> m a) -> m a Source #
Constructs a generator from three sub-term generators.
Shrinks to one of the sub-terms if possible.
Combinations & Permutations
subsequence :: MonadGen m => [a] -> m [a] Source #
Generates a random subsequence of a list.
shuffle :: MonadGen m => [a] -> m [a] Source #
Generates a random permutation of a list.
This shrinks towards the order of the list being identical to the input list.
Sampling Generators
print :: (MonadIO m, Show a) => Gen a -> m () Source #
Run a generator with a random seed and print the outcome, and the first level of shrinks.
Gen.print (Gen.enum
'a' 'f')
=== Outcome === 'd' === Shrinks === 'a' 'b' 'c'
printTree :: (MonadIO m, Show a) => Gen a -> m () Source #
Run a generator with a random seed and print the resulting shrink tree.
Gen.printTree (Gen.enum
'a' 'f')
'd' ├╼'a' ├╼'b' │ └╼'a' └╼'c' ├╼'a' └╼'b' └╼'a'
This may not terminate when the tree is very large.
printWith :: (MonadIO m, Show a) => Size -> Seed -> Gen a -> m () Source #
Print the value produced by a generator, and the first level of shrinks, for the given size and seed.
Use print
to generate a value from a random seed.
printTreeWith :: (MonadIO m, Show a) => Size -> Seed -> Gen a -> m () Source #
Print the shrink tree produced by a generator, for the given size and seed.
Use printTree
to generate a value from a random seed.
Internal
These functions are exported in case you need them in a pinch, but are not part of the public API and may change at any time, even as part of a minor update.
Transfomer
runGenT :: Size -> Seed -> GenT m a -> Tree (MaybeT m) a Source #
Runs a generator, producing its shrink tree.
mapGenT :: (Tree (MaybeT m) a -> Tree (MaybeT n) b) -> GenT m a -> GenT n b Source #
Map over a generator's shrink tree.
liftTree :: Tree (MaybeT m) a -> GenT m a Source #
Lift a predefined shrink tree in to a generator, ignoring the seed and the size.
Size
golden :: Size -> Size Source #
Scale a size using the golden ratio.
golden x = x / φ golden x = x / 1.61803..
Shrinking
atLeast :: Int -> [a] -> Bool Source #
Check that list contains at least a certain number of elements.
Characters
isSurrogate :: Char -> Bool Source #
Check if a character is in the surrogate category.
Subterms
subtermMVec :: MonadGen m => Vec n (m a) -> (Vec n a -> m a) -> m a Source #
Constructs a generator from a number of sub-term generators.
Shrinks to one of the sub-terms if possible.