[Haskell-cafe] QuickCheck

rodrigo.bonifacio rodrigo.bonifacio at uol.com.br
Sun Mar 16 15:19:22 EDT 2008


Dear Sebastian Sylvan,

Thanks for your datailed answer. It saved me a lot of time.

Best regards,

Rodrigo. 

> On Sun, Mar 16, 2008 at 5:42 PM, rodrigo.bonifacio <
> rodrigo.bonifacio at uol.com.br> wrote:
> 
> > Hi all,
> >
> > I'm trying to use the quick-check library for checking some properties of
> > a user defined data type. Bellow the target data type:
> >
> > data Feature =
> >  Feature Id Name FeatureType GroupType Children Properties |
> >  FeatureError
> >
> > where:
> >
> > Id = String
> > Name = String
> > FeatureType = int
> > GroupType = int
> > Children = [Feature]
> > Propertyes = [String]
> >
> >
> > I've written the following quick-check property:
> >
> > prop_AlternativeFeature :: Feature -> Feature -> QuickCheck.Property
> > prop_AlternativeFeature fm fc = length (children fc) == 0 ==> length
> >  (checkAlternativeFeature fm fc) > 0
> >
> > When I try to check such property, the result is:
> >
> > ERROR "./EshopModelChecking.hs":11 - Type error in instance member binding
> > *** Term           : arbitrary
> > *** Type           : Feature
> > *** Does not match : Gen Feature
> >
> > I think that I need to write some arbitrary or generator functions, but I
> > didn't realize how to do that with the availalble quick-checking
> > documentation.
> >
> > Any help will be welcome.
> >
> >
> You use the available functions to build up a generator for your data type.
> 
> First, let's give the instanc itself. For this I'm just going to use the
> frequency function to use "featureGenNormal" five times more often than
> "return FeatureError". This means that will get a FeatureError every now and
> then, but mostly you'll get featureGenNormal (see below). You can change
> these frequences, of course.
> 
> instance Arbitrary Feature where
>     arbitrary = do
>         frequency [ (5, featureGenNormal),  (1, return FeatureError) ]
> 
> In order to write featureGenNormal, we need to be able to generate random
> values of each of the parts of the data type. Often these types will already
> have Arbitrary instances, so generating an isntance for your type is quite
> often just a matter of calling "arbitrary" for each component, and then
> returning a datatype. However, there is no Arbitrary instance for String,
> which is a bit annoying, so let's write our own generator for strings.
> 
> First a generator for a single letter:
> 
> letterGen = oneof $ map return $ ['a'..'z'] ++ ['A'..'Z']
> 
> Then a combinator for generating a list of values given a generator for a
> single value:
> 
> listGen :: Gen a -> Gen [a]
> listGen g = do
>     x <- g
>     xs <- frequency [ (1, return []), (10, listGen g) ]
>     return (x:xs)
> 
> And then we use this to build our "stringGen" generator.
> 
> stringGen :: Gen String
> stringGen = listGen letterGen
> 
> Now, we have all we need to write the featureGenNormal generator:
> 
> featureGenNormal = do
>     id <- stringGen
>     name <- stringGen
>     featuretype <- arbitrary
>     grouptype <- arbitrary
>     children <- arbitrary
>     properties <- listGen stringGen
>     return (Feature id name featuretype grouptype children properties)
> 
> 
> Note that we use "arbitrary" to generate the list of children recursively.
> 
> -- 
> Sebastian Sylvan
> +44(0)7857-300802
> UIN: 44640862
> 

-----------------------------------
Rodrigo Bonifácio de Almeida
Universidade Católica de Brasília
 - Grupo de Engenharia de Software
 - JavaComBr (www.ucb.br/java)



More information about the Haskell-Cafe mailing list