<br><font size=2 face="sans-serif">I wanted to generate some random table
data, and decided to use quickcheck to do this. I didn't want to be checking
properties, I actually wanted to output the examples that quickcheck came
up with using arbitrary. In this case, I wanted to generate lists of lists
of strings.</font>
<br>
<br><font size=2 face="sans-serif">In case this is of use to anyone else
here's an example...</font>
<br>
<br><font size=2 face="sans-serif">One thing I don't understand is the
purpose of the first argument to generate. If it's zero it's always the
same data, so I made it a larger number (10000). Seems ok, but it would
be nice to understand why. Or if there is a better bway to accomplish this.</font>
<br>
<br><font size=2 face="sans-serif">t.</font>
<br>
<br>
<br><font size=2 face="Courier New">{-# OPTIONS -fno-monomorphism-restriction
#-}</font>
<br><font size=2 face="Courier New">module GenTestData where</font>
<br>
<br><font size=2 face="Courier New">import Test.QuickCheck</font>
<br><font size=2 face="Courier New">import Control.Monad</font>
<br><font size=2 face="Courier New">import System.Random</font>
<br><font size=2 face="Courier New">import Test.QuickCheck</font>
<br>
<br><font size=2 face="Courier New">import Misc</font>
<br><font size=2 face="Courier New">import ArbitraryInstances</font>
<br>
<br><font size=2 face="Courier New">f &gt;&gt;=^ g = f &gt;&gt;= return
. g</font>
<br><font size=2 face="Courier New">infixl 1 &gt;&gt;=^</font>
<br>
<br>
<br><font size=2 face="Courier New">rgenIntList = rgen (arbitrary :: Gen
[Int]) :: IO [Int]</font>
<br><font size=2 face="Courier New">rgenInt = rgen (arbitrary :: Gen Int)
:: IO Int</font>
<br><font size=2 face="Courier New">rgenFoo = rgen (arbitrary :: Gen Foo
) :: IO Foo</font>
<br><font size=2 face="Courier New">rgenFoos = rgen (arbitrary :: Gen [Foo])
:: IO [Foo]</font>
<br><font size=2 face="Courier New">rgenString' = rgen (arbitrary :: Gen
[Char]) :: IO [Char]</font>
<br><font size=2 face="Courier New">rgenString len = rgenString' &gt;&gt;=^
take len </font>
<br><font size=2 face="Courier New">rgenStringRow' = rgen (arbitrary ::
Gen [[Char]]) :: IO [[Char]]</font>
<br><font size=2 face="Courier New">rgenStringRow maxlenstr maxcols &nbsp;=
do</font>
<br><font size=2 face="Courier New">&nbsp; rgenStringRow'</font>
<br><font size=2 face="Courier New">&nbsp; &gt;&gt;=^ take maxcols </font>
<br><font size=2 face="Courier New">&nbsp; &gt;&gt;=^ map ( take maxlenstr
)</font>
<br><font size=2 face="Courier New">rgenStringTable' = rgen (arbitrary
:: Gen [[[Char]]]) :: IO [[[Char]]]</font>
<br><font size=2 face="Courier New">rgenStringTable maxlenstr maxcols maxrows
= do</font>
<br><font size=2 face="Courier New">&nbsp; rgenStringTable' </font>
<br><font size=2 face="Courier New">&nbsp; &gt;&gt;=^ take maxrows</font>
<br><font size=2 face="Courier New">&nbsp; &gt;&gt;=^ map ( take maxcols
)</font>
<br><font size=2 face="Courier New">&nbsp; &gt;&gt;=^ ( map . map ) (take
maxlenstr)</font>
<br>
<br><font size=2 face="Courier New">rgen gen = do</font>
<br><font size=2 face="Courier New">&nbsp; sg &lt;- newStdGen</font>
<br><font size=2 face="Courier New">&nbsp; return $ generate 10000 sg gen</font>
<br>
<br>
<br><font size=2 face="Courier New">module ArbitraryInstances where</font>
<br>
<br><font size=2 face="Courier New">import Test.QuickCheck</font>
<br><font size=2 face="Courier New">import Data.Char</font>
<br><font size=2 face="Courier New">import Control.Monad</font>
<br>
<br><font size=2 face="Courier New">instance Arbitrary Char where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; arbitrary &nbsp; &nbsp;
= choose ('\32', '\128')</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; coarbitrary c = variant
(ord c `rem` 4)</font>
<br>
<br><font size=2 face="Courier New">-- joel reymont's example I think</font>
<br><font size=2 face="Courier New">data Foo</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;= Foo Int</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;| Bar</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;| Baz</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp;deriving
Show</font>
<br>
<br><font size=2 face="Courier New">instance Arbitrary Foo where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;coarbitrary = undefined</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;arbitrary &nbsp;
= oneof [ return Bar</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;, return Baz</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;, liftM Foo arbitrary</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</font>
<br>
<br>
<span style="font-family:sans-serif,helvetica; font-size:10pt; color:#000000">---</span><br>
<br>
<span style="font-family:sans-serif,helvetica; font-size:10pt; color:#000000">This e-mail may contain confidential and/or privileged information. If you </span><br>
<span style="font-family:sans-serif,helvetica; font-size:10pt; color:#000000">are not the intended recipient (or have received this e-mail in error) </span><br>
<span style="font-family:sans-serif,helvetica; font-size:10pt; color:#000000">please notify the sender immediately and destroy this e-mail. Any </span><br>
<span style="font-family:sans-serif,helvetica; font-size:10pt; color:#000000">unauthorized copying, disclosure or distribution of the material in this </span><br>
<span style="font-family:sans-serif,helvetica; font-size:10pt; color:#000000">e-mail is strictly forbidden.</span><br>