【问题标题】:Why does shrinking stop once one of the terms is fully shrunk为什么一旦其中一项完全收缩,收缩就会停止
【发布时间】:2019-09-24 15:22:59
【问题描述】:

我在看shrink的cmets:

将最后一行写成[Branch x' l' r' | x' <- shrink x, l' <- shrink l, r' <- shrink r] 很诱人,但这是错误的!它将强制 QuickCheck 同时收缩 xlr,一旦三个中的一个完全收缩,收缩就会停止。

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

因此,换句话说,我认为上面的定义将计算所有收缩组合 xlr,但我不希望收缩停止一旦条款完全收缩.

【问题讨论】:

  • 是的,同意,也许这是一个错字,他们的意思是 [Branch x' l' r' | x' <- shrink x | l' <- shrink l | r' <- shrink r] 在平行列表推导流行的时候?

标签: haskell quickcheck


【解决方案1】:

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

x = 1
l = 0
r = 2

那么我们有

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

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

【讨论】:

  • 我明白了,所以也许应该将评论改写为如果三个中的一个完全收缩(而不是一次)收缩可以停止),或者类似的东西......
  • 我的意思是,即使没有完全收缩,我们也会跳过一些有效的收缩。想象一下 (1, 1, 1):有 7 个有效的收缩,但是对三个收缩的嵌套列表理解错过了像 (1, 0, 1) 这样的东西,只产生 (0, 0, 0)。
  • @DamianNadales 1. 不,正如它所说,如果其中一个组件完全收缩,收缩肯定会停止。因为那时你有像[... | x' <- [], ...] 这样的东西,这总是空的。 2. “and not once” 这里“once”的意思是“尽快”,而不是“一次”。
  • 另见successors 包,它为您提供了一个仿函数来模拟“一个领域中的一步”的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
相关资源
最近更新 更多