Often times QuickCheck properties are polymophic/overloaded without giving a monomorphic type signature. But there can be several types that you are interested. You can write scripts that check all the types you are interested annotating the generic property for each different monotype, which is a tedious work to do. Here, I automated this via hint (a Haskell Interpreter Library). How it works is it first asks a type of a property to the Haskell interpreter and gets a type string, identifies type variables that start with lowercase alphabet, generate all possible substitution that may or may not be a correct type, stick the type string to the property name as a signature and collect only the meaningful types, and then finally run quickCheck over each meaningful types. The example below clearly illustrates what it does.
P.S. If there is a way to work this out without hint and string manipulation I would be happy to hear that. I've tried template haskell but didn't work since you cannot test whether given type is correct or instance of some class; it should be correct in the first place, no way to recover from failure of type checking. import Test.QuickCheck.PolyQC import Prop -- the module that defiens the properties p0, p1, p2, p3, p4 -- p0 x = x == x -- p1 x y z = x + (y + z) == (x + y) + z -- p2 x y = x + y == y + x -- p3 x = x == negate (negate x) -- p4 p = (fst p, snd p) == p main = do putStrLn "testing p0 =======================================" print =<< polyQuickCheck' "Prop" "p0" ["Bool","Int","Double"] putStrLn "testing p1 =======================================" print =<< polyQuickCheck' "Prop" "p1" ["Bool","Int","Double"] putStrLn "testing p2 =======================================" print =<< polyQuickCheck' "Prop" "p2" ["Bool","Int","Double"] putStrLn "testing p3 =======================================" print =<< polyQuickCheck' "Prop" "p3" ["Bool","Int","Double"] putStrLn "testing p4 =======================================" print =<< polyQuickCheck' "Prop" "p4" ["Bool","Int","Double"] return () {- *Main> :t p0 p0 :: (Eq a) => a -> Bool *Main> :t p1 p1 :: (Num a) => a -> a -> a -> Bool *Main> :t p2 p2 :: (Num a) => a -> a -> Bool *Main> :t p3 p3 :: (Num a) => a -> Bool *Main> :t p4 p4 :: (Eq a, Eq b) => (a, b) -> Bool *Main> main testing p0 ======================================= Right ["(\"(Eq Bool) => Bool -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Int) => Int -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Double) => Double -> Bool\",+++ OK, passed 100 tests. ())"] testing p1 ======================================= Right ["(\"(Num Int) => Int -> Int -> Int -> Bool\",+++ OK, passed 100 tests. ())","(\"(Num Double) => Double -> Double -> Double -> Bool\",*** Failed! Falsifiable (after 9 tests and 2 shrinks): 4.0 -26.0 8.777291602197652 ())"] testing p2 ======================================= Right ["(\"(Num Int) => Int -> Int -> Bool\",+++ OK, passed 100 tests. ())","(\"(Num Double) => Double -> Double -> Bool\",+++ OK, passed 100 tests. ())"] testing p3 ======================================= Right ["(\"(Num Int) => Int -> Bool\",+++ OK, passed 100 tests. ())","(\"(Num Double) => Double -> Bool\",+++ OK, passed 100 tests. ())"] testing p4 ======================================= Right ["(\"(Eq Bool, Eq Bool) => (Bool, Bool) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Bool, Eq Int) => (Bool, Int) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Bool, Eq Double) => (Bool, Double) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Int, Eq Bool) => (Int, Bool) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Int, Eq Int) => (Int, Int) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Int, Eq Double) => (Int, Double) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Double, Eq Bool) => (Double, Bool) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Double, Eq Int) => (Double, Int) -> Bool\",+++ OK, passed 100 tests. ())","(\"(Eq Double, Eq Double) => (Double, Double) -> Bool\",+++ OK, passed 100 tests. ())"] -} _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell