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