我面临着为生成器编写收缩函数的问题,该函数取决于另一个生成器的输出值。基本上是以下形式的生成器:
do
a <- genA
b <- f a
pure $! g a b
其中genA :: Gen a
, f :: a -> Gen b
g :: a -> b -> c
. 为论证起见假设g = (,)
。那么问题是给定一对(a, b)
,收缩可能会破坏,和a
之间存在的关系。a
f
b
举个例子,考虑以下具有缓存长度的列表:
data List =
List
{ llength :: Int
, list :: [Int]
} deriving (Eq, Show)
该arbitrary
函数可以很容易地定义:
instance Arbitrary List where
arbitrary = do
n <- choose (0, 10)
xs <- vector n
pure $! List { llength = n, list = xs }
然而,缩小表单元素需要了解和List n xs
之间的关系。n
xs
在前面的示例中,这不是问题,因为 和 之间的关系n
很xs
容易确定,但是对于我正在解决的问题,确定这种关系并不是微不足道的。
像hedgehog
该功能集成收缩这样的库将解决这个特定问题(尽管并非总是如此),但是我想知道在QuickCheck
.
这是一个示例,显示如何hedgehog
找到列表长度小于 5 的属性的最小反例(它始终List 5 [ 0 , 0 , 0 , 0 , 0 ]
作为反例给出)。这是我(我认为我)目前如何解决这个问题的一个例子,基本上是通过模拟集成收缩。
另外,请注意,monadic 接口的行为在hedgehog
大多数情况下可能不是您想要的。