Haskell QuickCheck为具有许多输入变量的函数生成随机数据

eps*_*lbe 6 haskell quickcheck

我有一个具有以下类型签名的函数

rndListIndex :: Double -> Double -> Double -> Double
rndListIndex maxIdx r1 r2 = …
Run Code Online (Sandbox Code Playgroud)
  • 第一个输入应该是来自非负严格正整数的值
  • 第二个和第三个输入需要在闭合区间[0.0,1.0]内,否则该功能没有意义

该函数具有的属性

prop_alwaysLessThanMaxIdx idx r1 r2 = (rndListIndex idx r1 r2 <= idx)
Run Code Online (Sandbox Code Playgroud)

我怎么生成随机数据maxIdxr1,r2分开; 我知道函数,choose但不知道如何将它与多个输入变量一起使用.

现在我已经测试了固定的属性idx,这不是应该测试的方式.

ben*_*ofs 13

您必须使用QuickCheck中的forAll函数.它有以下类型:

forAll :: (Show a, Testable prop) 
       => Gen a           -- ^ The generator to use for generating values
       -> (a -> prop)     -- ^ A function which returns a testable property
       -> Property                  
Run Code Online (Sandbox Code Playgroud)

forAll 有两个参数:

  • 生成器描述了如何生成值.发电机的例子有选择,随心所欲,oneof,...
  • 该函数测试给定输入的属性.它必须返回一个值,该值的一个实例Testable,例如另一个Property,Bool或功能.

使用choose和elements生成器嵌套forAll的示例:

-- This generates a Property p for all x's in the closed interval [1,3]
-- The property p in turn generates a property q for all y ? [4,5]
-- The property q is True if x < y.
prop_choose = forAll (choose (1,3)) $ \x ->
              forAll (elements [4,5]) $ \y -> x < y
Run Code Online (Sandbox Code Playgroud)

对于您的测试属性,您可以使用forAll选择第二个和第三个参数.对于第一个参数,Positive aQuickCheck中的类型可用于生成类型a的任意正值(当a为Num时,它具有任意实例):

prop_alwayLessThanMaxIdx :: Positive Integer -> Property
prop_alwaysLessThanMaxIdx (Positive idx) = 
  forAll (choose (0,1)) $ \r1 ->
  forAll (choose (0,1)) $ \r2 ->
   (rndListIndex idx r1 r2) < idx
Run Code Online (Sandbox Code Playgroud)