Tony Morris | 8 Nov 02:20 2013
Picon

QuickCheck

Hello,
I have implemented a function for QuickCheck:

untilJust :: Gen a -> (a -> Maybe b) -> Gen b

I based it on the code for suchThat[1] and suchThatMaybe[2].

I am wondering if I have potentially re-implemented an existing function
in part or full. In other words, is there an easier way of achieving
this function without pulling the generator apart as much as I have in
this implementation: http://lpaste.net/95317

[1]
suchThat :: Gen a -> (a -> Bool) -> Gen a
http://hackage.haskell.org/package/QuickCheck-2.6/docs/src/Test-QuickCheck-Gen.html#suchThat

[2]
suchThatMaybe :: Gen a -> (a -> Bool) -> Gen (Maybe a)
http://hackage.haskell.org/package/QuickCheck-2.6/docs/src/Test-QuickCheck-Gen.html#suchThatMaybe

--

-- 
Tony Morris
http://tmorris.net/
Nickolay Kudasov | 8 Nov 09:40 2013
Picon

Re: QuickCheck

Hi Tony,

​​Take a look at monad-loops package [1].
Seems like you reinvented a version of untilJust [2].
​​
Your version can be obtained by:

yourUntilJust :: (Monad m) => m a -> (a -> Maybe b) -> m b yourUntilJust m f = untilJust (liftM f m)

Best,
Nick

[1] http://hackage.haskell.org/package/monad-loops
[2] http://hackage.haskell.org/package/monad-loops-0.4.2/docs/Control-Monad-Loops.html#v:untilJust



2013/11/8 Tony Morris <tonymorris <at> gmail.com>
Hello,
I have implemented a function for QuickCheck:

untilJust :: Gen a -> (a -> Maybe b) -> Gen b

I based it on the code for suchThat[1] and suchThatMaybe[2].

I am wondering if I have potentially re-implemented an existing function
in part or full. In other words, is there an easier way of achieving
this function without pulling the generator apart as much as I have in
this implementation: http://lpaste.net/95317

[1]
suchThat :: Gen a -> (a -> Bool) -> Gen a
http://hackage.haskell.org/package/QuickCheck-2.6/docs/src/Test-QuickCheck-Gen.html#suchThat

[2]
suchThatMaybe :: Gen a -> (a -> Bool) -> Gen (Maybe a)
http://hackage.haskell.org/package/QuickCheck-2.6/docs/src/Test-QuickCheck-Gen.html#suchThatMaybe

--
Tony Morris
http://tmorris.net/

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
rodrigo.bonifacio | 16 Mar 20:19 2008
Picon

Re: QuickCheck

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)
rodrigo.bonifacio | 17 Mar 14:37 2008
Picon

Re: QuickCheck

Hi all,

Is it possible to define a limit for the size of children list bellow? 

I've tried:

children <- resize (10 (listGen featureGenNormal))

But it didn't work.

Thanks a lot,

Rodrigo.

> Sebastian Sylvan:
> >> featureGenNormal = do
> >>     id <- stringGen
> >>     name <- stringGen
> >>     featuretype <- arbitrary
> >>     grouptype <- arbitrary
> >>     children <- arbitrary
> >>     properties <- listGen stringGen
> >>     return (Feature id name featuretype grouptype children properties)
> 
> Ryan Ingram wrote:
> >  Also, you can shorten this significantly with liftM or ap (from Control.Monad):
> 
> True, but in this case I like being able to see meaningful
> names for each parameter of the constructor.
> 

-----------------------------------
Rodrigo Bonifácio de Almeida
Universidade Católica de Brasília
 - Grupo de Engenharia de Software
 - JavaComBr (www.ucb.br/java)
Henning Thielemann | 17 Mar 14:42 2008
Picon

Re: QuickCheck


On Mon, 17 Mar 2008, rodrigo.bonifacio wrote:

> Hi all,
>
> Is it possible to define a limit for the size of children list bellow?

take 10 ?
Thomas Schilling | 17 Mar 14:54 2008

Re: QuickCheck


On 17 mar 2008, at 14.37, rodrigo.bonifacio wrote:

> Hi all,
>
> Is it possible to define a limit for the size of children list bellow?
>
> I've tried:
>
> children <- resize (10 (listGen featureGenNormal))
>>

You are calling a number as a function.

Also, listGen has to use the size argument.  Try something like (not  
tested):

   listGen =
     sized (\maxSize -> do
         n <- arbitrary
         x <- g
         xs <- frequency [ (1, return []), (n, listGen g) ]
         return (x:xs)
Sebastian Sylvan | 17 Mar 19:02 2008
Picon

Re: QuickCheck



On Mon, Mar 17, 2008 at 1:54 PM, Thomas Schilling <nominolo <at> googlemail.com> wrote:

On 17 mar 2008, at 14.37, rodrigo.bonifacio wrote:

> Hi all,
>
> Is it possible to define a limit for the size of children list bellow?
>
> I've tried:
>
> children <- resize (10 (listGen featureGenNormal))
>>

You are calling a number as a function.

Also, listGen has to use the size argument.  Try something like (not
tested):

  listGen =
    sized (\maxSize -> do
        n <- arbitrary
        x <- g
        xs <- frequency [ (1, return []), (n, listGen g) ]
        return (x:xs)

In retrospect, this function isn't very good at all, because it never generates the empty list... Something like this is probably better (untested):

listGen g = sized (\maxSize -> do
   count <- choose (0, maxSize - 1)
   replicateM count g )
  

--
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane