Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show-ing functions used in QuickCheck properties

I'm trying to write a QuickCheck property that takes one or more functions as input. To keep things simple, consider a property to check that function composition is equivalent to successive function application, and a quick-and-dirty test driver:

import Test.QuickCheck

prop_composition :: (Int -> Int) -> (Int -> Int) -> Int -> Bool
prop_composition f g x = (f . g) x == f (g x)

main :: IO ()
main = quickCheck prop_composition

Unfortunately, this doesn't compile, because the inputs to a property need to implement Show so that QuickCheck can report what inputs caused the failure, but there's no Show implementation for functions:

Test.hs:10:7:
    No instance for (Show (Int -> Int))
      arising from a use of `quickCheck' at Test.hs:10:7-33
    Possible fix: add an instance declaration for (Show (Int -> Int))
    In the expression: quickCheck prop_composition
    In the definition of `main': main = quickCheck prop_composition

I've tried writing my own do-nothing instance of Show for functions...

instance Show (a -> b) where
    show _ = "[func]"

... which compiles, but triggers a warning with -Wall...

Test.hs:3:9: Warning: orphan instance: instance Show (a -> b)

... which makes me think there's a more correct way to do this.

My gut tells me the answer lies in the Test.QuickCheck.Function module, but it's undocumented, and I can't figure out just from looking at the type signatures what anything in there is for or how it's intended to be used.

like image 675
Paul Kuliniewicz Avatar asked Mar 06 '11 04:03

Paul Kuliniewicz


People also ask

What is property based testing QuickCheck?

What Is Property-Based Testing? Property-based testing (PBT) is the approach to software testing that implies an automatic check of the function properties (predicates) specified by the tester. Checking, i.e. search for counter-examples is carried out using the automatically generated input data.

How does QuickCheck work Haskell?

QuickCheck is a tool for testing Haskell programs automatically. The programmer provides a specification of the program, in the form of properties which functions should satisfy, and QuickCheck then tests that the properties hold in a large number of randomly generated cases.

How do I import a QuickCheck into ghci?

If you want to use QuickCheck in a command such as stack ghci or stack ghc , you can add it as a --package option e.g. to run a REPL to play around with QuickCheck you can use stack ghci --package QuickCheck and then write import Test. QuickCheck .

Is Haskell QuickCheck static?

Two domain-specific languages (DSLs) are used for this purpose, one for each component. The original QuickCheck technique was based on DSLs embedded into Haskell using a Haskell library [6]. Since then, the approach has been ported to numerous other programming languages, both statically and dynamically typed.


2 Answers

You are right Test.QuickCheck.Function is the right answer. You just change the types:

prop_composition       :: Fun Int Int -> Fun Int Int -> Int -> Bool
prop_composition f g x = ((apply f) . (apply g)) x == (apply f) ((apply g) x)
like image 97
edon Avatar answered Oct 17 '22 14:10

edon


The import Text.Show.Functions could also be used with keeping the original signature.

like image 31
gliptak Avatar answered Oct 17 '22 16:10

gliptak