mardi 28 février 2017

How to efficiently generate random tests in Haskell Test.QuickCheck

I'd like to generate some sample tests using Haskell Test.QuickCheck

The goal is to generate data of (Int, [Int]) with the following conditions where the tuple is (x, xs):

  1. x > 0
  2. x not in xs
  3. all xs >0

Scratching my head and stumbling through the manual http://ift.tt/2m4pjDK after some time I can produce random lists meeting these requirements:

import Test.QuickCheck
mygen = arbitrary::Gen (Int, [Int]))
sample (mygen `suchThat` ( \(x, xs)->( (x `notElem` xs) && (x > 0) && (all (>0) xs)&& (xs/=[]))))

Running the last line in the GHCI outputs something like:

(40,[19,35,27,29,45,1,17,28])
(20,[3,9,11,12,15,8])
(43,[76,102,106,71,24,2,29,101,59,48])
(99,[5,87,136,131,22,22,133])
(77,[11,14,55,47,78,15,14])
...

Questions:

  1. How can this be done more efficiently since - I'm guessing- the function mygen creates a large sample set then filters out based on the suchThat criteria

  2. How can I indicate the list xs should be of a certain size. For example if I add && length xs > 50 the program runs for a very long time.

  3. Guarantee that each element of xs is unique. I.e. avoid records like (99,[22,22])

Aucun commentaire:

Enregistrer un commentaire