Haskell QuickCheck generate random data for function with many input variables
haskell, quickcheck
Solution
You have to use the forAll function from QuickCheck. It has the following type:
forAll :: (Show a, Testable prop)
=> Gen a -- ^ The generator to use for generating values
-> (a -> prop) -- ^ A function which returns a testable property
-> Property
`forAll` takes two arguments:
- The generator describes how to generate values. Examples of generators are choose, arbitrary, oneof, ...
- The function tests the property for the given input. It must return a value that is an instance of `Testable`, for example another `Property`, `Bool` or a function.
Example of a nested forAll with the choose and elements generators:
-- This generates a Property p for all x's in the closed interval [1,3]
-- The property p in turn generates a property q for all y ∈ [4,5]
-- The property q is True if x < y.
prop_choose = forAll (choose (1,3)) $ \x ->
forAll (elements [4,5]) $ \y -> x < y
For your test property, you can use forAll with choose for the second and third argument. For the first argument, there is the `Positive a` type in QuickCheck which can be used to generate arbitrary positive values of type a (It has an Arbitrary instance when a is a Num):
prop_alwayLessThanMaxIdx :: Positive Integer -> Property
prop_alwaysLessThanMaxIdx (Positive idx) =
forAll (choose (0,1)) $ \r1 ->
forAll (choose (0,1)) $ \r2 ->
(rndListIndex idx r1 r2) < idx
Problem
I have a function with the following type signature ``` rndListIndex :: Double -> Double -> Double -> Double rndListIndex maxIdx r1 r2 = … ``` - the first input should be a value coming from a non-negative strictly positive integer - the second and third input are required to be within the closed interval [0.0,1.0] otherwise the function makes no sense the function has the property of ``` prop_alwaysLessThanMaxIdx idx r1 r2 = (rndListIndex idx r1 r2 <= idx) ``` how do I generate random data for `maxIdx` and `r1`,`r2` separately; I know of the function `choose`but do not know how to use it with more than one input variable. For now I have tested the Property with fixed `idx`, which is not the way it should be tested.