有誰知道到底如何使用QuickCheck在Haskell中定義一個生成器,以便選擇的元素只被選中一次?Haskell QuickCheck獨特的隨機數生成
我已經意識到我可能需要一個「Gen(Maybe Positive)」生成器,但當然會產生重複的數字。我需要它,以便選擇的數字不會重複。在數字返回的實例中,我想只返回並且在randoms全部耗盡的情況下,我希望Gen Nothing返回。
感謝,
馬克
有誰知道到底如何使用QuickCheck在Haskell中定義一個生成器,以便選擇的元素只被選中一次?Haskell QuickCheck獨特的隨機數生成
我已經意識到我可能需要一個「Gen(Maybe Positive)」生成器,但當然會產生重複的數字。我需要它,以便選擇的數字不會重複。在數字返回的實例中,我想只返回並且在randoms全部耗盡的情況下,我希望Gen Nothing返回。
感謝,
馬克
你不能。看看definition of Gen
。它沒有辦法對迄今爲止選擇的東西進行任何說明。給定相同的隨機生成器和大小限制,它必須始終生成相同的結果。你可以然而寫一個Eq a => Gen [a]
生成一個列表值沒有重複。一個簡單的(但有點天真的)會是這樣的。
uniques :: Eq a => Gen a -> Gen [a]
uniques gen = fmap nub $ listOf gen
您可以使用permutations
(模塊Data.List
)這一點。
這裏是permutations
函數簽名:
permutations :: [a] -> [[a]]
正如你所看到的,它返回一個列表的列表。這裏是一個小例子(使用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]]
所以,你可以這樣做:
prop_unique_elements = forAll (elements (permutations [1..3])) $ \x -> foo == bar
我沒有測試過,因此將需要一些按摩,但我希望它清楚地表達了這一點。祝你好運。
QuickCheck通常用於隨機測試,而不是詳盡的測試。 做有幾個偉大的庫處理窮舉測試 - 看看smallcheck和lazysmallcheck。
的xorshift隨機發生器設計沒有重複。你可以試試它。 (上面的語句適用於前2^64左右的數字 – fuz
Hrm。我認爲有可能每次使用CoArbitrary選擇不同的發生器(某種程度?),範圍受限制/限制 – Mark