如何在QuickCeck中使用shuffle生成测试数据

时间:2017-02-12 09:35:02

标签: haskell quickcheck

对于给定列表[1..n],其中n是一个随机正整数,我想用两步生成测试数据:

  1. 随机播放列表,xs = shuffle [1..n];
  2. 随机改变xs中的数字x到y,其中1 <= y <= n;
  3. 在这两个步骤之后,新列表表示为ys。

    我写了一个程序。它需要ys和输出(x,y),函数原型是这样的:

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

    我想用Test.QuickCheck来测试我的程序。如何生成这样的测试数据?我看到QuickCheck中有一个函数

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

    但我不知道如何使用它。

1 个答案:

答案 0 :(得分:2)

QuickCheck中的Gen monad基本上是一个状态monad,其随机数生成器作为其状态。所以,当你看到

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

这意味着这个参数采用一个列表并返回一个洗牌列表&#34;在&#34; Gen monad。

因为它是monad你可以把它放在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在Gen monad中运行操作,该操作会返回IO中的值,或者您可以为测试数据设置新类型并使其成为{{ 1}},包含函数

Arbitrary

编辑或者正如Zeta在评论中指出的那样,您可以使用arbitrary :: Gen a

forAll