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.