
Whenever I want to use quickCheck to test some function with multiple input parameters, I end up writing boilerplate code that looks like the example below. I have a feeling I'm missing out on some good Haskell tricks. In particular, writing a function like arbXYZ for every combination of parameter types that I need to test is a bit repetitive. Is there a better way? Thank you in advance, Amy ----- code example ----- functionIWantToTest :: Double -> Int -> Bool -> Double functionIWantToTest x y z = 27 -- pretend we're doing something useful arbXYZ :: Gen (Double, Int, Bool) arbXYZ = do x <- choose (0.0, 1.0) y <- choose (1, 10) z <- arbitrary return (x, y, z) conditionIWantToCheck :: (Double, Int, Bool) -> Bool conditionIWantToCheck (x, y, z) = True -- pretend we're checking something prop_i_want_to_check :: Property prop_i_want_to_check = forAll arbXYZ conditionIWantToCheck

Hello Andy, Gen is a funny typeclass, in particular I can write something like: prop_foo x y z = {- do something with x y z -} and QuickCheck will automatically fill in x, y, z using arbitrary from the inferred type classes. This will work fine for z but no so much for x and y in your example, in which case you can create newtypes that encodes things like [bounded from 0.0 to 1.0], etc. I often find hanging lambda style with forAll to be quite palatable, so I frequently find myself writing things like: conditionIWantToCheck z = forAll (choose (0.0, 1.0)) $ \x -> forAll (choose (1, 10)) $ \y -> {- condition -} Especially when the inner forAlls have dependencies on earlier forAlls, this style is quite natural. Cheers, Edward Excerpts from Amy de Buitléir's message of Thu Sep 23 17:56:39 -0400 2010:
Whenever I want to use quickCheck to test some function with multiple input parameters, I end up writing boilerplate code that looks like the example below. I have a feeling I'm missing out on some good Haskell tricks. In particular, writing a function like arbXYZ for every combination of parameter types that I need to test is a bit repetitive. Is there a better way?
Thank you in advance, Amy
----- code example -----
functionIWantToTest :: Double -> Int -> Bool -> Double functionIWantToTest x y z = 27 -- pretend we're doing something useful
arbXYZ :: Gen (Double, Int, Bool) arbXYZ = do x <- choose (0.0, 1.0) y <- choose (1, 10) z <- arbitrary return (x, y, z)
conditionIWantToCheck :: (Double, Int, Bool) -> Bool conditionIWantToCheck (x, y, z) = True -- pretend we're checking something
prop_i_want_to_check :: Property prop_i_want_to_check = forAll arbXYZ conditionIWantToCheck

Thank you, Edward. That hanging lambda style looks particularly useful for my purposes.
participants (2)
-
Amy de Buitléir
-
Edward Z. Yang