为什么一旦其中一个术语完全收缩,收缩就会停止

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.

对此我有点疑惑,我认为收缩的问题在于我们采用的是子项收缩的笛卡尔积,这可能非常大。我不明白为什么一旦三个之一完全收缩,收缩就会停止。

所以换句话说,我认为上面的定义会计算 xlr 收缩的所有组合,但我不希望收缩停止一旦其中一项条款完全缩小。

建议的代码 是错误的,因为我们只考虑将所有三个项至少缩小一步的收缩。要查看问题,假设所有三个候选人都是 Int:

x = 1
l = 0
r = 2

然后我们有

shrink x = [0]
shrink l = []
shrink r = [1, 0]

对这三个列表的嵌套列表理解将不会产生任何值,因为找不到 l 的合适候选项。所以我们从不尝试像 (0, 0, 1) 这样的有效收缩。元组的 shrink 实例做了正确的事情(建议每个收缩 至少一个 项可以收缩),因此映射解决了问题。