Suppose I write tests for Data.Set. I would like to verify that removing items from the set works, and so I can write something like this:
prop_deleteA it x = member x it ==> not (member x (delete x it))
assuming it ithas a suitable instance Arbitrary. However, this depends on the quickcheck values generating the values xthat exist in the set, which is usually not guaranteed. It would be much better if xyou could depend on itto ensure that you are xalready a member it. How can i do this?
I had a thought that I could write
prop_deleteB it f = let x = f it
in not (member x (delete x it))
where f :: Set a -> asuitably determined using coarse. However, a coarbitrary would allow us to determine f :: Set a -> bthat, unfortunately, is not what we want. So far I have been thinking about defining a new type
data SetAndElement a = SetAndElement (Set a) a
allowing you to write a suitable instance 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)
allows you to prop_deleterecord as
prop_deleteC (SetAndElement it x) = not (member x (delete x it))
It works, but seems a bit involved; are there any better options? (If not, I will change the question and put this as the answer.) The actual implementation Data.Set(container package) checks the deletion, checking that (delete x) . (insert x) == idif it xhas not been a member of this set.