我正在查看shrink
中的评论:
很容易将最后一行写为
shrink
,但这是错误的事情!它将强制QuickCheck依次缩小[Branch x' l' r' | x' <- shrink x, l' <- shrink l, r' <- shrink r]
,x
和l
,并且一旦三个中的一个完全缩小,缩小将停止。
我对此有些疑惑,我认为收缩的问题在于我们采用了子项收缩的笛卡尔积,该乘积可能会很大。我不明白为什么一旦三个部分中的一个完全收缩,收缩将停止。
换句话说,我认为上面的定义将计算r
,x
和l
收缩的所有组合,但我不希望一旦这些术语完全收缩,收缩就不会停止。
建议的代码是是错误的,因为我们仅考虑将所有三个术语至少收缩一步的收缩。要查看该问题,假设所有三个候选者均为r
:
Int
那么我们有
x = 1
l = 0
r = 2
对这三个列表的嵌套列表理解将不会产生任何值,因为找不到适合shrink x = [0]
shrink l = []
shrink r = [1, 0]
的候选对象。因此,我们永远不会尝试像l
这样的有效收缩。元组的(0, 0, 1)
实例做正确的事情(建议每次缩水,其中至少一个]项可以缩小),因此在该位置进行映射可以解决问题。