2017-02-12 81 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