简体   繁体   中英

QuickCheck Generator not terminating

This QuickCheck generator

notEqual :: Gen (Int, Int)
notEqual = do
  (a, b) <- arbitrary
  if a /= b
    then return (a, b)
    else notEqual

Doesn't seem to terminate when passed to forAll . I'm guessing the recursion is going into an infinite loop somehow, but why?

If you are in doubt of termination/finding results you can always try to circumvent this:

notEqual' :: Gen (Int, Int)
notEqual' = do
  start <- arbitrary
  delta <- oneof [pos, neg]
  pure (start, start + delta)
  where
      pos = getPositive <$> arbitrary
      neg = getNegative <$> arbitrary

Of course internally both Postitive and Negative use suchThat so as Ashesh mentioned

notEqual :: Gen (Int, Int)
notEqual = genPair `suchThat` uncurry (/=)
  where genPair = arbitrary

might be easier

The suchThat combinator that @Ashesh and @Carsten pointed out is definitely what I am looking for, to succinctly and idiomatically generate a non-equal pair.

An explanation for the infinite recursion (Thanks to @oisdk):

All QuckCheck runners ( quickCheck , forAll etc.) pass a size parameter to test genarators. This has no defined semantics, but early tests use a small parameter, starting at 0*, and gradually growing. Generators use this to generate samples of different 'sizes,' whatever that may mean for a specific datatype.

arbitrary for integral types (called recursively by arbitrary for (Int, Int) ), uses this for the magnitude of the generated value - generate an integral between 0 and size .

This means, unfortunately, that the first test attempted by quickCheck , (or in my case forAll ,) uses the size 0, which can only generate (0, 0) . This always fails the test of /= , causing the action to recurse infinitely, looking for more.

* I'm assuming this, as the behaviour of the size parameter doesn't seem to be documented anywhere.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM