QuickCheck: why isn't there a function to pass a test and what to use instead?
Asked Answered
V

2

6

Why isn't there a QuickCheck function similar to hedgehog's success? In particular I was wondering how one could translate a property like the following one:

prop_specialPair :: Property
prop_specialPair = property $ do
  (_, xs) <- forAll specialPair
  case xs of
    x:_ -> x /== 3
    _   -> success

In QuickCheck if I use =/= then I'm forced to return something of type Property, and there seem to be no constant function to return a passing property.

So I either have to resort to the Bool type:

prop_specialPair :: SpecialPair -> Bool
prop_specialPair SpecialPair { xs } =
  case xs of
    x:_ -> x == 3
    _   -> True

Or use a very awkward encoding for success, e.g.:

prop_specialPair :: SpecialPair -> Property
prop_specialPair SpecialPair { xs } =
  case xs of
    x:_ -> x =/= 3
    _   -> True === True

Are there better ways to express the property above in QuickCheck?

Voluntarism answered 17/12, 2019 at 22:41 Comment(0)
I
8

You can use the property function from the Testable class, and various Testable instances to create a Property with whatever characteristics you need.

For example, property () always succeeds. For another example, property (b :: Bool) succeeds iff b == True.

So you could do this for example:

prop_specialPair :: SpecialPair -> Property
prop_specialPair SpecialPair { xs } =
  case xs of
    x:_ -> x =/= 3
    _   -> property ()

Or you can make it more explicit by using the Testable Result instance and the value succeeded :: Result:

prop_specialPair :: SpecialPair -> Property
prop_specialPair SpecialPair { xs } =
  case xs of
    x:_ -> x =/= 3
    _   -> property succeeded
Intendance answered 17/12, 2019 at 23:2 Comment(1)
A couple of weeks later I realize I should have also asked about how to mark a property as failing ...Voluntarism
Q
1

You could also use implication with (==>):

prop_specialPair :: Property
prop_specialPair =
  forAll specialPair $ \(_, xs) ->
    not (null xs) ==> take 1 xs =/= [3]
Quimper answered 18/12, 2019 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.