[Haskell-beginners] QuickCheck Crazy

Dimitri DeFigueiredo defigueiredo at ucdavis.edu
Fri Oct 17 03:55:11 UTC 2014


Hello Everyone,

I am trying to do homework #3 of Stephanie Weirich's programming class. 
It is about QuickCheck.
http://www.seas.upenn.edu/~cis552/current/hw/hw03/index.html

However, quickCheck is magically coming up with the wrong answer!
I am loading a very simple file (distilled from the homework). Here it is:

~~~~
import Test.QuickCheck

------------------------------------------------------------------------------
prop_const :: Eq a => (a -> a -> a) -> a -> a -> Bool
prop_const const' a b = const' a b == a

const_bug :: a -> b -> b
const_bug _ b = b -- Oops: this returns the *second* argument, not the 
first.

--main = quickCheck (prop_const const)

~~~~
Now, I just wanted to check that 'prop_const' holds for the 'const' 
function, but fails for 'const_bug'
So, I fired up GHCi, but here's what happens:

econ1gw-131-21-dhcp:week3 dimitri$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l weird-quickcheck.hs
[1 of 1] Compiling Main             ( weird-quickcheck.hs, interpreted )

weird-quickcheck.hs:22:1: Warning:
     The import of `Test.QuickCheck' is redundant
       except perhaps to import instances from `Test.QuickCheck'
     To import instances alone, use: import Test.QuickCheck()
Ok, modules loaded: Main.
*Main> const 1 2
1
*Main> const_bug 1 2
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package old-locale-1.0.0.5 ... linking ... done.
Loading package time-1.4.0.1 ... linking ... done.
Loading package random-1.0.1.1 ... linking ... done.
Loading package primitive-0.5.0.1 ... linking ... done.
Loading package pretty-1.1.1.0 ... linking ... done.
Loading package containers-0.5.0.0 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package tf-random-0.5 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package QuickCheck-2.7.6 ... linking ... done.
2
*Main> :t prop_const
prop_const :: Eq a => (a -> a -> a) -> a -> a -> Bool
*Main> quickCheck (prop_const const)
+++ OK, passed 100 tests.
*Main> quickCheck (prop_const const_bug)
+++ OK, passed 100 tests.
*Main> quickCheck (prop_const const_bug :: Char -> Char -> Bool)
*** Failed! Falsifiable (after 1 test and 2 shrinks):
'a'
'b'
*Main>

This makes no sense to me!
First, I have no idea how quickCheck is able to run any tests at all as 
the type of 'const' is:
*Main> :t const
const :: a -> b -> a

In other words, it's a polymorphic type.

Second, why does GHCi load so many files when I try to evaluate 'const_bug'?

Finally and most puzzling, why does quickCheck give out the wrong result 
if I don't specify the type when testing 'const_bug'?
That's really scary. It means that quickCheck can easily fool me if I 
forget to specify the necessary types.

(GHC complains if I uncommented the '--main' line, so I can only do this 
in GHCi.)

I am totally lost here, any pointers would be much appreciated.

Thanks,

Dimitri




More information about the Beginners mailing list