Search code examples
haskelltestingquickcheck

Only generate positive integers with QuickCheck


We have two functions that compare two different power functions, and return true if they return the same value (on the same input).

Then we have two other functions that test these functions against two lists to see if there is any value that doesn't return true.

But instead of using lists that use a range [1..100], we would like to use QuickCheck.

Is it possible to make QuickCheck only return positive integers?

Code:

comparePower1 :: Integer -> Integer -> Bool
comparePower1 n k = power n k == power1 n k

comparePower2 :: Integer -> Integer -> Bool
comparePower2 n k = power n k == power2 n k

testing1 = and [comparePower1 n k | n <- [0..100], k <- [0..100]]
testing2 = and [comparePower2 n k | n <- [0..100], k <- [0..100]]

Solution

  • QuickCheck has support for Positive numbers, but for the sake of this tutorial I will show you how to create your own Generator. One of the main features of QuickCheck is that you can design your own generator to output just what you need. For instance

    genPos :: Gen Int
    genPos = abs `fmap` (arbitrary :: Gen Int) `suchThat` (> 0)
    

    Then you can create your own list genereator

    genListOfPos :: Gen [Int]
    genListOfPos = listOf genPos
    

    Finally you can use forAll, pass the generator and profit.

    main :: IO ()
    main = do
      quickCheck $ forAll genPos $ \x -> x > 0
      quickCheck $ forAll genListOfPos $ all (> 0)