Haskell: QuickCheck property fails tests using implications
Asked Answered
A

1

6

I've got the following property I want to test using quickcheck:

prop_zip xs ys = length xs == length ys ==> 
    unzip (zip xs ys) == (xs,ys)

Eventhough it seems to be logically right according to the definition of zip and unzip, that this property should be correct fo lists of the same length, the quickcheck ends with:

*** Gave up! Passed only 49 tests.

Thanks in advance for any hint or advice!

Adham answered 10/2, 2014 at 11:5 Comment(1)
Quickcheck generates two random lists for every test case. It then discards them if xs and ys are not of the same length. I suspect that the two lists are almost never of the same length, so almost all generated test cases are discarded, until quickcheck gives up.Anelace
R
14

Preconditions that are difficult to meet by generating random test cases are often a bad idea in QuickCheck. Instead, you should use generators carefully to construct test cases that meet the precondition automatically.

For example, in this case, you can use forAll to generate the second list to be of the same length as the first list:

prop_zip' (xs :: [a]) =
  forAll (vectorOf (length xs) arbitrary) $ \ (ys :: [a]) ->
  unzip (zip xs ys) == (xs, ys)

(I'm additionally using ScopedTypeVariables here to determine the type of the second list. You might want to change this to suit your specific needs.)

Remonstrate answered 10/2, 2014 at 11:26 Comment(3)
You could reach the same objective with asTypeOfZimmermann
I thought the term length xs == length ys ==> would ensure, that the check is applied to lists of the same length only.Adham
Yes, it does ensure this. But it'll still randomly generate two lists, and the probability that two randomly generated lists are of equal length is not very high. That's what's causing QuickCheck to give up. See also the comment by fjh.Remonstrate

© 2022 - 2024 — McMap. All rights reserved.