为什么一旦其中一个术语完全收缩,收缩就会停止
Why does shrinking stop once one of the terms is fully shrunk
我正在查看 shrink
中的评论:
It is tempting to write the last line as [Branch x' l' r' | x' <- shrink x, l' <- shrink l, r' <- shrink r]
but this is the wrong thing! It will force QuickCheck to shrink x
, l
and r
in tandem, and shrinking will stop once one of the three is fully shrunk.
对此我有点疑惑,我认为收缩的问题在于我们采用的是子项收缩的笛卡尔积,这可能非常大。我不明白为什么一旦三个之一完全收缩,收缩就会停止。
所以换句话说,我认为上面的定义会计算 x
、l
和 r
收缩的所有组合,但我不希望收缩停止一旦其中一项条款完全缩小。
建议的代码 是错误的,因为我们只考虑将所有三个项至少缩小一步的收缩。要查看问题,假设所有三个候选人都是 Int
:
x = 1
l = 0
r = 2
然后我们有
shrink x = [0]
shrink l = []
shrink r = [1, 0]
对这三个列表的嵌套列表理解将不会产生任何值,因为找不到 l
的合适候选项。所以我们从不尝试像 (0, 0, 1)
这样的有效收缩。元组的 shrink
实例做了正确的事情(建议每个收缩 至少一个 项可以收缩),因此映射解决了问题。
我正在查看 shrink
中的评论:
It is tempting to write the last line as
[Branch x' l' r' | x' <- shrink x, l' <- shrink l, r' <- shrink r]
but this is the wrong thing! It will force QuickCheck to shrinkx
,l
andr
in tandem, and shrinking will stop once one of the three is fully shrunk.
对此我有点疑惑,我认为收缩的问题在于我们采用的是子项收缩的笛卡尔积,这可能非常大。我不明白为什么一旦三个之一完全收缩,收缩就会停止。
所以换句话说,我认为上面的定义会计算 x
、l
和 r
收缩的所有组合,但我不希望收缩停止一旦其中一项条款完全缩小。
建议的代码 是错误的,因为我们只考虑将所有三个项至少缩小一步的收缩。要查看问题,假设所有三个候选人都是 Int
:
x = 1
l = 0
r = 2
然后我们有
shrink x = [0]
shrink l = []
shrink r = [1, 0]
对这三个列表的嵌套列表理解将不会产生任何值,因为找不到 l
的合适候选项。所以我们从不尝试像 (0, 0, 1)
这样的有效收缩。元组的 shrink
实例做了正确的事情(建议每个收缩 至少一个 项可以收缩),因此映射解决了问题。