Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QuickCheck: defining Arbitrary instance in terms of other Arbitraries

I'm using QuickCheck 1 and I've got the following data types:

data A = ...
instance Arbitrary A where ...
data B = ...
instance Arbitrary B where ...
data C = C A B

Now I'd like to define an Arbitrary instance for C so that C values are generated using existing generators for A and B. I ended up doing this:

instance Arbitrary C where
  arbitrary = elements [(C a b) |
                        a <- generate 20 (System.Random.mkStdGen 0) arbitrary,
                        b <- generate 20 (System.Random.mkStdGen 0) arbitrary]

Is this explicit generation of a fixed number of values for A and B necessary, or is there a better way of combining existing Arbitraries into a new one?

like image 742
narthi Avatar asked Feb 27 '11 16:02

narthi


1 Answers

I'd do it like this:

instance Arbitrary C
  where arbitrary = do a <- arbitrary
                       b <- arbitrary
                       return (C a b)

Although sclv's idea of using liftM2 from Control.Monad is probably better:

instance Arbitrary C
  where arbitrary = liftM2 C arbitrary arbitrary
like image 189
dave4420 Avatar answered Nov 16 '22 01:11

dave4420