Using quickCheck
Asked Answered
F

3

6

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
F answered 24/4, 2013 at 20:40 Comment(0)
C
7

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.

Crustacean answered 24/4, 2013 at 21:47 Comment(0)
K
6

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]
Kafir answered 25/4, 2013 at 2:17 Comment(7)
Not in scope: type constructor or class `Blind'F
@chamini2: Have you imported Test.QuickCheck?Kafir
yes, maybe because I'm on OS X?ghci --version: The Glorious Glasgow Haskell Compilation System, version 7.4.2F
@chamini2: Which version of QuickCheck are you using?Kafir
I don't know how to check thatF
@chamini2: Run ghc-pkg list QuickCheck.Kafir
let us continue this discussion in chatKafir
W
2

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.

Whitby answered 24/4, 2013 at 21:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.