【发布时间】:2016-02-21 05:22:05
【问题描述】:
假设我正在为Data.Set 编写测试。我想检查从集合中删除元素是否有效,所以我可能会写这样的东西:
prop_deleteA it x = member x it ==> not (member x (delete x it))
假设it 有一个合适的Arbitrary 实例。但是,这依赖于在集合中碰巧存在的 x 的快速检查生成值,这通常不能保证。如果可以使x 依赖于it 以保证x 已经是it 的成员,那就更好了。我该怎么做?
我认为我可以写作
prop_deleteB it f = let x = f it
in not (member x (delete x it))
其中f :: Set a -> a 适当地通过coarbitrary 定义。然而,coarbitrary 只允许我们定义f :: Set a -> b,不幸的是这不是我们想要的。到目前为止,我最好的想法是定义一个新类型
data SetAndElement a = SetAndElement (Set a) a
这允许我们编写一个合适的Arbitrary 实例
instance (Ord a, Arbitrary a) => Arbitrary (SetAndElement a) where
arbitrary = do it <- suchThat arbitrary (not . Set.null)
x <- elements (elems it)
return (SetAndElement it x)
允许prop_delete 写成
prop_deleteC (SetAndElement it x) = not (member x (delete x it))
这可行,但似乎有点复杂;有没有更好的选择? (如果不是,我将修改问题并将其作为答案。)实际的Data.Set 实现(容器包)通过检查(delete x) . (insert x) == id 如果x 还不是给定集合的成员来测试删除。
【问题讨论】:
标签: haskell quickcheck