Reputation: 2073
For a given list [1..n], where n is a random positive integer, I want to generate the test data with 2 steps:
After these 2 steps, the new list is denoted as ys.
I wrote a program. It takes ys, and outputs (x, y), the function prototype is like this:
solve :: [a] -> (a, a)
I want to use Test.QuickCheck to test my program. How to generate such test data? I see there is a function in QuickCheck
shuffle :: [a] -> Gen [a]
But I have no idea about how to use it.
Upvotes: 1
Views: 236
Reputation: 17786
The Gen
monad in QuickCheck is basically a state monad with a random number generator as its state. So when you see
shuffle :: [a] -> Gen [a]
That means that this argument takes a list and returns a shuffled list "in" the Gen
monad.
Because its a monad you can put it inside a do
clause. Its not quite clear what you are asking for, but I think its something like this:
myTest :: Integer -> Gen [Integer]
myTest 0 = return []
myTest n = do
ns <- shuffle [1..n]
x <- choose (0,n-1)
y <- choose (1,n)
let (ns1,ns2) = splitAt x ns
return $ ns1 ++ [y] ++ drop 1 ns2`
You can run an action in the Gen monad using generate
, which returns a value in IO
, or you can set up a new type for your test data and make it an instance of Arbitrary
, which contains the function
arbitrary :: Gen a
Edit: Or as Zeta pointed out in the comments you can use forAll
:
quickCheck $ forAll (myTest 10) $ \x -> ....
Upvotes: 2