Daniel Fischer daniel.is.fischer at web.de
Mon Nov 1 14:40:38 EDT 2010

```On Monday 01 November 2010 19:18:33, Jacek Generowicz wrote:
> I'm toying with generating random objects (for example tuples) and
> started wondering what pearls of wisdom Cafe might have on the matter.
> Two obvious points (relating to my toy code, shown below) are
>
> 1) The meaning of the limits required by randomR is not obvious for
> types such as tuples

But there's a pretty natural one, much like the Ix instance for tuples:

randomR ((x1,y1),(x2,y2)) g0 = ((x,y),g2)
where
(x,g1) = randomR (x1,x2) g0
(y,g2) = randomR (y1,y2) g1

Of course, if there is an Ord instance, it would be tempting to use the
limits as bounds for that, i.e.

randomR (p1,p2) g

should produce a pair p with p1 <= p <= p2, but that's not particularly
nice to implement (in particular, if you don't want skewed sample
distributions).

> (you could come up with some definition, but it
> wouldn't be unique: how would you allow for different ones?[*];

newtype

> you
> might decide that having such limits is nonsensical and not want to
> provide a randomR: would you then leave it undefinded?).

Yes.

>
> [*] I guess this is related to issues such as Num being both a sum and
> and product monoid.
>
> 2) I'm sure there are at least half a dozen prettier definitions of
> random.
>
> But I suspect that the juicy bits will be in offerings about issues
> that I haven't even dreamed about.
>
> Presumably QuickCheck's test-data generation mechanism would be
> interesting to look at in this context. Is there a gentle explanation
> of how it works somewhere?
>
>
>
> Here's my initial effort:
>
> import System.Random
>
> main :: IO (Int, Int)
> main = randomIO
>
> instance (Random a, Random b) => Random (a, b) where
>      randomR = undefined
>      random g0 = let (i1,g1) = random g0
>                      (i2,g2) = random g1
>                  in ((i1,i2), g1)

```