[Haskell-cafe] QuickCheck Questions
Kevin Quick
quick at sparq.org
Sun Jul 24 21:14:24 CEST 2011
On Sun, 24 Jul 2011 07:30:56 -0700, Mark Spezzano
<mark.spezzano at chariot.net.au> wrote:
> Hi all,
>
> I would appreciate it if someone can point me in the right direction
> with the following problem.
>
> I'm deliberately implementing a naive Queues packages that uses finite
> lists as the underlying representation. I've already read through
> Hughes' paper and the article in The Fun of Programming, but I'm still
> having some difficulties. Specifically:
>
> 1. I have a newtype Queue a = Queue [a] and I want to generate Queues of
> random Integers that are also of random size. How do I do this in
> QuickCheck? I guess that I need to write a generator and then make my
> "Queue a" concrete type an instance of Arbitrary? How?
Mark,
One of the great things about QuickCheck is that it is automatically
compositional.
What I mean by this is that all you need in your instance is how to form a
"Queue [a]" given "[a]", because there are already QuickCheck instances
for forming lists, and as long as a is pretty standard (Integers is fine)
then there's likely an Arbitrary instance for that as well.
So (from my head, not actually tested in GHC):
import Control.Applicative
import Test.QuickCheck
instance Arbitrary Queue where
arbitrary = Queue <$> arbitrary
Then you can use this as:
testProperty "length is something" propQInts
propQInts t = length t == ....
where types = (t :: Queue Integers)
The where clause is a fancy way of specifying what the type of t should be
without having to express the overall type of propQInts. You could use a
more conventional type specification as well.
>
> 2. If I wanted to specify/constrain the ranges of random Integers
> generated, how would I do this?
Probably something like this:
instance Arbitrary Queue where
arbitrary = do li <- listOf $ arbitrary
lr <- liftM $ map rangelimit li
return $ Queue lr
where rangelimit n = case (n < LOW, n > HIGH) of
(True,_) -> LOW
(_,True) -> HIGH
_ -> n
>
> 3. If I wanted to specify/constrain the Queue sizes how would I do this?
Similar to #2. Perhaps:
arbitrary = arbitrary >>= (return . Queue . take CNT . listOf)
--
-KQ
More information about the Haskell-Cafe
mailing list