Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using quickCheck

I wrote an implementation for foldl and wanted to check if it worked, I tried some cases and it seems to be working well but I want to make sure.

I read about quickCheck and tried it, but I can't seem to make it work, this is the code

foldl'' :: (b -> a -> b) -> b -> [a] -> b

test :: Eq b => (b -> a -> b) -> b -> [a] -> Bool
test f e ls = foldl'' f e ls == foldl f e ls

when I run quickCheck test it throws the following error:

No instance for (Show (b0 -> a0 -> b0))
  arising from a use of `quickCheck'
Possible fix:
  add an instance declaration for (Show (b0 -> a0 -> b0))
In the expression: quickCheck prueba
In an equation for `it': it = quickCheck prueba
like image 484
chamini2 Avatar asked Apr 24 '13 20:04

chamini2


3 Answers

Your property requires three inputs: a function, an element and a list. The problem is that QuickCheck does not know how to deal with functions in general.

One of the things QuickCheck needs to work, is the ability to write failing test cases to the console. For this, it needs values it can turn into a String--anything in the Show class. Since functions are not in Show, it can't use them for inputs. That's where your error message comes from.

In general, using randomly generated functions for testing is going to be pretty tricky. I'd just write some concrete functions instead and let QuickCheck randomly generate the starting value and the list of elements.

like image 190
Tikhon Jelvis Avatar answered Sep 27 '22 19:09

Tikhon Jelvis


There is a way to avoid the Show constraint on inputs using the Blind modifier, which will let you use QuickCheck's machinery for generating random functions.

-- Using Int instead of a, b which would be defaulted to () in GHCi
prueba :: Blind (Int -> Int -> Int) -> Int -> [Int] -> Bool
prueba (Blind f) e ls = foldl'' f e ls == foldl f e ls

That said, this means the failure output is nearly useless for debugging, as it will just print (*) for the blind input. (For demonstration, I defined foldl'' = foldr . flip)

> quickCheck prueba 
*** Failed! Falsifiable (after 4 tests and 2 shrinks):    
(*)
0
[1,0]
like image 35
hammar Avatar answered Sep 27 '22 18:09

hammar


From what I understand, there is machinery for creating random functions in QuickCheck (see Test.QuickCheck.Function), but I can't say that I known this stuff well enough to tell you how to use it.

That being said, testing your property likely makes more sense with functions you choose yourself, so you could write something like quickCheck $ prueba (+), which will work fine.

like image 36
Julien Langlois Avatar answered Sep 27 '22 18:09

Julien Langlois