2017-02-12 80 views
0

對於給定的名單[1..1],其中n是一個隨機的正整數,我想用2個步驟生成測試數據:如何使用隨機生成QuickCeck測試數據

  1. 洗牌列表,xs = shuffle [1..n];
  2. 隨機將xs中的數字x變爲x,其中1 < = y < = n;

經過這2個步驟後,新列表被表示爲ys。

我寫了一個程序。這需要Ys和輸出(X,Y),該函數的原型是這樣的:

solve :: [a] -> (a, a) 

我想用Test.QuickCheck來測試我的程序。如何生成這樣的測試數據?我認爲只有在快速檢查

shuffle :: [a] -> Gen [a] 

功能,但我不知道如何使用它的想法。

回答

2

QuickCheck中的Gen monad基本上是一個以隨機數發生器作爲狀態的狀態monad。所以當你看到

shuffle :: [a] -> Gen [a] 

這意味着,這種說法接受一個列表,並返回「中的」 Gen單子改組名單。

因爲它的單子,你可以把它放在do子句中。它不是很清楚你問什麼,但我認爲它是這樣的:

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` 

可以使用generate運行在創單子的動作,這在IO返回一個值,也可以設置一個新型的測試數據,並使它成爲Arbitrary一個實例,其中包含了功能

arbitrary :: Gen a 

編輯:或者像Zeta在評論中指出,你可以使用forAll

quickCheck $ forAll (myTest 10) $ \x -> .... 
+0

謝謝。我創建了一個Sample數據類型,並提供了這個任意函數。像這樣:https://github.com/liuxinyu95/AlgoXY/blob/algoxy/others/problems/miss-dup/MissDup.hs –

+0

或者你使用'quickCheck $ forAll(myTest 10)$ \ x - > ... '。 – Zeta