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.
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.
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.
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 .
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.
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)
The import Text.Show.Functions
could also be used with keeping the original signature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With