
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