2
votes

Given the following test code using QuickCheck, I would expect that prop_Max errMax should fail as the definition of errMax is incorrect.

This happens when I use the given signature for prop_Max with the concrete type Int. However when I give it the more polymorphic commented-out type using Ord, the test passes. Why is this?

import Test.QuickCheck

myMax :: Ord a => a -> a -> a
myMax x y  
    |x > y = x
    |otherwise = y

errMax :: Ord a => a -> a -> a
errMax x y
    |x > y = y
    |otherwise = x


-- prop_Max :: Ord a => (a -> a -> a) -> a -> a -> Bool
prop_Max :: (Int -> Int -> Int) -> Int -> Int -> Bool
prop_Max maxFunc x y = (x <= maxFunc x y) && (y <= maxFunc x y)

-- in ghci
-- quickCheck (prop_Max max)
-- quickCheck (prop_Max myMax)
-- quickCheck (prop_Max errMax)
1
What error do you get if you try the other signature?GS - Apologise to Monica
@GaneshSittampalam, if I use prop_Max::Ord a=>(a->a->a)->a->a->Bool, then, quickCheck (prop_Max errMax) will pass the testAlaya
Then what's your problem?GS - Apologise to Monica
why would that signature cause error on test result?Alaya
What "error on test result" do you get?GS - Apologise to Monica

1 Answers

4
votes

The problem is with defaulting.

In ghci by default, the ExtendedDefaultRules extension is turned on. That means that with the general Ord-based type signature, the a type variable is defaulted to the () type.

Since the only valid value of the type () is the value (), your test passes even for a definition of max that would be incorrect on a more complicated type.

With QuickCheck tests, you should generally be explicit about the type you expect the test to run on. So here you could keep the polymorphic signature for prop_Max, but explicitly select Int when you call quickCheck:

quickCheck (prop_Max (errMax :: Int -> Int -> Int))