当我偶然发现growingElements函数时,我正在浏览QuickCheck的文档。那里的文件说
获取一个增加大小的元素列表,并选择一个 列表的初始部分。此初始段的大小 随size参数增加。输入列表必须为非空。
这究竟是什么意思?当我在ghci中尝试此功能时,
当我一次又一次地运行generate
时,它只返回给定数组中的随机值。我没有看到从列表中随机选择与此功能正在做什么之间的区别。
*Main Test.QuickCheck> generate $ growingElements [1..100]
13
*Main Test.QuickCheck> generate $ growingElements [1..100]
53
*Main Test.QuickCheck>
*Main Test.QuickCheck> generate $ growingElements [1..100]
65
*Main Test.QuickCheck> generate $ growingElements [1..100]
49
*Main Test.QuickCheck>
有人可以更清楚地解释这个功能实际上做了什么吗?
答案 0 :(得分:3)
QuickCheck有一个"尺寸参数"它控制随机生成的输入有多大。它首先生成较小的测试输入,并在运行越来越多的测试时增加它们。
QuickCheck手册进入more detail关于此:
测试数据生成器具有隐式 size 参数;
quickCheck
从生成小测试用例开始,随着测试的进行逐渐增加大小。不同的测试数据生成器以不同的方式解释大小参数:一些忽略它,而列表生成器例如将其解释为生成列表长度的上限。您可以随意使用它,因为您希望控制自己的测试数据生成器。
在growingElements
的情况下,size参数控制生成器在随机选择条目时进入列表的距离。
如果您想自己使用size
参数,可以使用sized
组合器:
sized :: (Int -> Gen a) -> Gen a
这使您可以编写自己的Gen a
值,这些值取决于传入的大小。这是growingElements
的样子:
growingElements' xs = sized (\ size -> oneOf (take size xs))
如果您想了解现有growingElements
在不同尺寸下的行为,您可以使用resize
功能修复特定尺寸。尝试
resize 1 (growingElements [1..])
应该只从列表的开头返回小数字。 (我查了the actual implementation并且它使用了一些繁琐的算术来根据大小参数选择元素的数量,所以我懒得弄清楚它的表现方式:))。