Haskell QuickCheck Unique Random Number Generation
Does anyone know exactly how to define a generator in Haskell using QuickCheck such that chosen elements are picked only ONCE?
I've gotten as far as realizing that I might need a "Gen (Maybe Positive)" generator, but of course that will generate number with repetition. I want it so that the numbers chosen are picked without repetition. In the instanc开发者_JAVA百科e when a number is returned I want Just returned and in the instance where the randoms are all exhausted I want Gen Nothing returned.
Thanks,
Mark
You can't. Look at the definition of Gen
. There's no way for it to carry any state about what has been picked so far. Given the same random generator and size limit it must always generate the same result. You can however write a Eq a => Gen [a]
that generates a list of values with no repetitions. A simple (but somewhat naive) one would be something like this.
uniques :: Eq a => Gen a -> Gen [a]
uniques gen = fmap nub $ listOf gen
QuickCheck is generally for randomized testing, not exhaustive testing. There are a few great libraries that do handle exhaustive testing -- look at smallcheck and lazysmallcheck.
You can use permutations
(in module Data.List
) for this.
Here is the function signature for permutations
:
permutations :: [a] -> [[a]]
As you can see, it returns a list of lists. Here is a little example (using GHCi 7.0.4):
> permutations [1..3]
[[1,2,3],[2,1,3],[3,2,1],[2,3,1],[3,1,2],[1,3,2]]
So you could do something like:
prop_unique_elements = forAll (elements (permutations [1..3])) $ \x -> foo == bar
I haven't tested that so it will need some massaging, but I hope it conveys the point clearly. Good luck.
精彩评论