Running QuickCheck against Simple Test w/ Function
Asked Answered
W

1

7

Given the following:

test :: (Int -> Int) -> Int -> Bool
test _ _ = True

After compiling the source, I try to run quickCheck test:

> quickCheck test
<interactive>:27:1:
    No instance for (Show (Int -> Int))
      arising from a use of ‘quickCheck’
    In the expression: quickCheck test
    In an equation for ‘it’: it = quickCheck test

Looking at this Show instance for functions, it appears to me that no such instance exists.

How can I run quickCheck test, i.e. get around or address the missing Show instance for Int -> Int?

Worm answered 22/9, 2015 at 2:27 Comment(0)
F
8

QuickCheck has a special module Test.QuickCheck.Function for generating "functions" that can be showed (and also "shrinked", which is how QuickCheck simplifies its counterexamples). You can convert them to ordinary functions using apply. For example if you have the file:

import Test.QuickCheck
import Test.QuickCheck.Function

test :: Fun Int Int -> Int -> Bool
test _ _ = True

test2 :: Fun Int Int -> Int -> Bool
test2 f x = apply f x == x

Then in GHCi:

*Main> quickCheck test
+++ OK, passed 100 tests.
*Main> quickCheck test2
*** Failed! Falsifiable (after 2 tests and 3 shrinks): 
{_->0}
1

It is actually possible to define a Show instance for functions themselves, and use that. But unless your input type is a finite type like Bool, you won't be able to print all information about the function this way. You can import a dummy instance that shows no useful information from Text.Show.Functions.

However, the Test.QuickCheck.Function.Fun type used above looks like it's been designed to give the essential information much more succinctly, so I'd certainly use that myself if possible.

Forefather answered 22/9, 2015 at 3:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.