简体   繁体   中英

How to generate arbitrary instances of a simple type for quickcheck

I have a simple type definition:

data Cell = Cell {
    x       :: Int,
    y       :: Int
  } deriving (Show)

I can't use Cell as an input to a quickcheck property, presumably because quickcheck doesn't know how to generate Cell values.

My understanding is that I need to make Cell an instance of the Arbitrary typeclass.

How do I do that, for example, if I'd like Cell to be generated with random positive values for x and y?

Writing an instance of Arbitrary for your data type is easy. You just have to implement the arbitrary function, which should return a Gen Cell . The simplest way to do this is to make use of existing Arbitrary instances and also note that Gen is a monad, so we can use do -notation:

instance Arbitrary Cell where
   arbitrary = do
     Positive x <- arbitrary
     Positive y <- arbitrary
     return $ Cell x y

Alternatively, generators can often be written elegantly using operators from Control.Applicative :

instance Arbitrary Cell where
   arbitrary = Cell <$> pos <*> pos
     where pos = getPositive <$> arbitrary  -- getPositive requires QC >= 2.5

Here, I've also made use of the Positive modifier from Test.QuickCheck.Modifiers to ensure that we only generate positive integers.

For writing more complex generators, have a look at the various generators from Test.QuickCheck.Gen .

You can generate an Arbitrary instance doing the same using TemplateHaskell and derive package:

import Data.DeriveTH

derive makeArbitrary ''Cell

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM