StrictCheck-0.1.0: StrictCheck: Keep Your Laziness In Check

Safe HaskellNone
LanguageHaskell2010

Test.StrictCheck.Produce

Contents

Description

This module defines the Produce typeclass, used for generating random values for testing in StrictCheck.

Produce is a strict generalization of Test.QuickCheck's Arbitrary typeclass. Paired with Consume (a generalization of CoArbitrary) it can be used to create random non-strict functions, whose strictness behavior is dependent on the values given to them.

Synopsis

Documentation

class Produce b where Source #

Produce an arbitrary value of type b, such that destructing that value incrementally evaluates some input to a function.

Writing instances of Produce is very similar to writing instances of QuickCheck's Arbitrary. The distinction: when making a recursive call to produce a subfield of a structure, always use build or recur, and never a direct call to produce itself. This ensures that the input can potentially be demanded at any step of evaluation of the produced value.

If, in the course of generating a value of type b, you need to generate a random value of some other type, which is not going to be a subpart of the resultant b (e.g. a length or depth), use a direct call to arbitrary or some other generator which does not consume input.

An example instance of Produce:

data D a
  = X a
  | Y [Int]

instance Produce a => Produce (D a) where
  produce =
    oneof [ fmap X recur
          , fmap Y recur
          ]

Minimal complete definition

produce

Methods

produce :: (?inputs :: Inputs) => Gen b Source #

Instances

Produce Bool Source # 

Methods

produce :: Gen Bool Source #

Produce Char Source # 

Methods

produce :: Gen Char Source #

Produce Double Source # 
Produce Float Source # 
Produce Int Source # 

Methods

produce :: Gen Int Source #

Produce Integer Source # 
Produce Ordering Source # 
Produce Rational Source # 
Produce Word Source # 

Methods

produce :: Gen Word Source #

Produce () Source # 

Methods

produce :: Gen () Source #

Produce Omega Source # 
Produce KMap Source #

A dummy produce instance for the solution table.

Methods

produce :: Gen KMap Source #

Produce Key Source #

A dummy produce instance for the index into the solution table.

Methods

produce :: Gen Key Source #

Produce a => Produce [a] Source # 

Methods

produce :: Gen [a] Source #

Produce a => Produce (Maybe a) Source # 

Methods

produce :: Gen (Maybe a) Source #

(Arbitrary a, RealFloat a) => Produce (Complex a) Source # 

Methods

produce :: Gen (Complex a) Source #

(Consume a, Produce b) => Produce (a -> b) Source # 

Methods

produce :: Gen (a -> b) Source #

(Produce a, Produce b) => Produce (Either a b) Source # 

Methods

produce :: Gen (Either a b) Source #

Tools for writing Produce instances

recur :: (Produce a, ?inputs :: Inputs) => Gen a Source #

Destruct some inputs to generate an output. This function handles the interleaving of input destruction with output construction. When producing a data type, it should be called to produce each subfield -- *not* produce itself.

build :: (?inputs :: Inputs) => ((?inputs :: Inputs) => Gen a) -> Gen a Source #

Given an input-consuming producer, wrap it in an outer layer of input consumption, so that this consumption can be interleaved when the producer is called recursively to generate a subfield of a larger produced datatype.

Producing non-strict functions

returning :: (Consume a, ?inputs :: Inputs) => ((?inputs :: Inputs) => Gen b) -> Gen (a -> b) Source #

Create an input-consuming producer of input-consuming functions, given an input-consuming producer for results of that function.

variadic :: forall args result. (All Consume args, Curry args, ?inputs :: Inputs) => ((?inputs :: Inputs) => Gen result) -> Gen (args ⋯-> result) Source #

Create an input-consuming producer of input-consuming functions, of any arity. This will usually be used in conjuntion with type application, to specify the type(s) of the argument(s) to the function.

Integration with Test.QuickCheck's Arbitrary

newtype Lazy a Source #

We hook into QuickCheck's existing Arbitrary infrastructure by using a newtype to differentiate our special way of generating things.

Constructors

Lazy 

Fields

Instances

Produce a => Arbitrary (Lazy a) Source # 

Methods

arbitrary :: Gen (Lazy a) #

shrink :: Lazy a -> [Lazy a] #

freely :: ((?inputs :: Inputs) => Gen a) -> Gen a Source #

Actually produce an output, given an input-consuming producer. If a function is to be produced, it will be almost-certainly non-strict.

Abstract types representing input to a function

data Input Source #

A tree representing all possible destruction sequences for a value Unfolding the contained lists forces a particular random control path for destructing the datatype.

data Inputs Source #

A list of inputs given to a function, in abstract form. This lazy structure is evaluated piecewise during the course of producing a function, thus triggering the partial evaluation of the original input to the function.

The traversal distribution for processing Inputs

draws :: [Input] -> Gen (Variant, [Input]) Source #

Destruct a random subpart of the given Inputs, returning the Variant corresponding to the combined information harvested during this process, and the remaining "leaves" of the inputs yet to be destructed

To maximize the likelihood that different random consumption paths through the same value will diverge (desirable when generating functions with interesting strictness), draws destructs the forest of Inputs as a depth-first random traversal with a budget sampled from a geometric distribution with expectation 1.