Search code examples
haskellquickcheck

Complete minimal example for using quickCheckAll


I could use a complete example of how to use quickCheckAll. Here's what I've tried so far:

In a file A.hs:

module A where
    import Test.QuickCheck

    prop_a = 1 == 0

    check = do
        return []
        $quickCheckAll

In another file that's supposed to drive the tests:

import A

main :: IO ()
main = do
    check

This doesn't work, because check doesn't have type IO (). How I am supposed to "execute check" as instructed in the documentation?


Solution

  • I think you misread the documentation a bit. It specifies that you should write return [] as a naked expression, and that you have to use TemplateHaskell:

    Test all properties in the current module, using Template Haskell. You need to have a {-# LANGUAGE TemplateHaskell #-} pragma in your module for any of these to work.

    (...)

    To use quickCheckAll, add a definition to your module along the lines of

    return []
    runTests = $quickCheckAll
    

    and then execute runTests.

    (...)

    Note: the bizarre return [] in the example above is needed on GHC 7.8; without it, quickCheckAll will not be able to find any of the properties. For the curious, the return [] is a Template Haskell splice that makes GHC insert the empty list of declarations at that point in the program; GHC typechecks everything before the return [] before it starts on the rest of the module, which means that the later call to quickCheckAll can see everything that was defined before the return []. Yikes!

    So your first file should be:

    {-# LANGUAGE TemplateHaskell #-}
    
    module A where
    
    import Test.QuickCheck
    
    prop_a = 1 == 0
    
    return []
    check = $quickCheckAll

    all properties you want to test (here prop_a) should be defined before the return [].

    and the main file:

    import A
    
    main :: IO Bool
    main = check

    You are allowed to use do, but it does not add any value. Or in case you want the main to be IO (), you can write:

    import A
    
    main :: IO ()
    main = do
        check
        return ()

    Running this in ghci gives:

    *A> :t check
    check :: IO Bool
    *A> check
    === prop_a from ha.hs:7 ===
    *** Failed! Falsifiable (after 1 test):  
    
    False