6

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?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Guillaume Chérel
  • 1,478
  • 8
  • 17

1 Answers1

7

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
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • 1
    Indeed, I got confused. Thank you. I found out thought that I had to edit the function main: `main = do check; return ()` to give it type IO (). `check` has type IO Bool – Guillaume Chérel Mar 08 '17 at 11:14
  • @GuillaumeChérel: as far as I know any `IO a` as `main` is acceptable. But indeed now it conflicts with the type signature. – Willem Van Onsem Mar 08 '17 at 11:49