QuickCheck 生成器未终止
QuickCheck Generator not terminating
这个 QuickCheck 生成器
notEqual :: Gen (Int, Int)
notEqual = do
(a, b) <- arbitrary
if a /= b
then return (a, b)
else notEqual
传递给 forAll
时似乎没有终止。我猜递归会以某种方式进入无限循环,但为什么呢?
如果您对 termination/finding 结果有疑问,您可以随时尝试规避这一点:
notEqual' :: Gen (Int, Int)
notEqual' = do
start <- arbitrary
delta <- oneof [pos, neg]
pure (start, start + delta)
where
pos = getPositive <$> arbitrary
neg = getNegative <$> arbitrary
当然,Postitive
和 Negative
在内部都使用 suchThat
,所以正如 Ashesh 提到的那样
notEqual :: Gen (Int, Int)
notEqual = genPair `suchThat` uncurry (/=)
where genPair = arbitrary
可能更容易
@Ashesh 和@Carsten 指出的 suchThat
组合子绝对是我正在寻找的,简洁地和惯用地生成一个不相等的对。
无限递归的解释(感谢@oisdk):
所有 QuckCheck 运行程序(quickCheck
、forAll
等)通过 size parameter 来测试生成器。这没有定义语义,但早期测试使用一个小参数,从 0* 开始,逐渐增长。生成器使用它来生成不同 'sizes,' 的样本,无论这对特定数据类型可能意味着什么。
arbitrary
用于整数类型(由 arbitrary
递归调用 (Int, Int)
),将其用于生成值的大小 - generate an integral between 0和 size
.
这意味着,不幸的是,quickCheck
尝试的 第一次测试 (或者在我的情况下 forAll
)使用大小 0,它只能生成(0, 0)
。这总是无法通过/=
的测试,导致动作无限递归,寻找更多。
* 我假设是这样,因为大小参数的行为似乎没有在任何地方记录。
这个 QuickCheck 生成器
notEqual :: Gen (Int, Int)
notEqual = do
(a, b) <- arbitrary
if a /= b
then return (a, b)
else notEqual
传递给 forAll
时似乎没有终止。我猜递归会以某种方式进入无限循环,但为什么呢?
如果您对 termination/finding 结果有疑问,您可以随时尝试规避这一点:
notEqual' :: Gen (Int, Int)
notEqual' = do
start <- arbitrary
delta <- oneof [pos, neg]
pure (start, start + delta)
where
pos = getPositive <$> arbitrary
neg = getNegative <$> arbitrary
当然,Postitive
和 Negative
在内部都使用 suchThat
,所以正如 Ashesh 提到的那样
notEqual :: Gen (Int, Int)
notEqual = genPair `suchThat` uncurry (/=)
where genPair = arbitrary
可能更容易
@Ashesh 和@Carsten 指出的 suchThat
组合子绝对是我正在寻找的,简洁地和惯用地生成一个不相等的对。
无限递归的解释(感谢@oisdk):
所有 QuckCheck 运行程序(quickCheck
、forAll
等)通过 size parameter 来测试生成器。这没有定义语义,但早期测试使用一个小参数,从 0* 开始,逐渐增长。生成器使用它来生成不同 'sizes,' 的样本,无论这对特定数据类型可能意味着什么。
arbitrary
用于整数类型(由 arbitrary
递归调用 (Int, Int)
),将其用于生成值的大小 - generate an integral between 0和 size
.
这意味着,不幸的是,quickCheck
尝试的 第一次测试 (或者在我的情况下 forAll
)使用大小 0,它只能生成(0, 0)
。这总是无法通过/=
的测试,导致动作无限递归,寻找更多。
* 我假设是这样,因为大小参数的行为似乎没有在任何地方记录。