2011-07-26 145 views
3

有誰知道到底如何使用QuickCheck在Haskell中定義一個生成器,以便選擇的元素只被選中一次?Haskell QuickCheck獨特的隨機數生成

我已經意識到我可能需要一個「Gen(Maybe Positive)」生成器,但當然會產生重複的數字。我需要它,以便選擇的數字不會重複。在數字返回的實例中,我想只返回並且在randoms全部耗盡的情況下,我希望Gen Nothing返回。

感謝,

馬克

回答

4

你不能。看看definition of Gen。它沒有辦法對迄今爲止選擇的東西進行任何說明。給定相同的隨機生成器和大小限制,它必須始終生成相同的結果。你可以然而寫一個Eq a => Gen [a]生成一個列表值沒有重複。一個簡單的(但有點天真的)會是這樣的。

uniques :: Eq a => Gen a -> Gen [a] 
uniques gen = fmap nub $ listOf gen 
+2

的xorshift隨機發生器設計沒有重複。你可以試試它。 (上面的語句適用於前2^64左右的數字 – fuz

+0

Hrm。我認爲有可能每次使用CoArbitrary選擇不同的發生器(某種程度?),範圍受限制/限制 – Mark

0

您可以使用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

我沒有測試過,因此將需要一些按摩,但我希望它清楚地表達了這一點。祝你好運。

+0

我不認爲FORALL做什麼,你認爲它。 – sclv

+0

@sclv我怎麼覺得呢?我一直以爲是宣佈通用量化爲發電機在謂詞。:)這顯然不能窮盡每運行一次排列,但是從每個結果正如問題所要求的那樣,生成器將成爲一個具有獨特元素的列表。 – Brandon

+0

然後,我們只是有這個問題的不同解讀 - 我把它讀作要求的詳盡測試 - 即選擇一個獨特的元素爲每個測試,而不是要求所產生的每個測試不同的元素列表發電機,但也有可能在不同的測試中產生相同的列表。 – sclv

3

QuickCheck通常用於隨機測試,而不是詳盡的測試。 有幾個偉大的庫處理窮舉測試 - 看看smallchecklazysmallcheck