
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 (you could come up with some definition, but it wouldn't be unique: how would you allow for different ones?[*]; you might decide that having such limits is nonsensical and not want to provide a randomR: would you then leave it undefinded?). [*] 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 Control.Monad 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)

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 Control.Monad 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)

On 2010-11-01 19:18 +0100, 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 (you could come up with some definition, but it wouldn't be unique: how would you allow for different ones?[*]; you might decide that having such limits is nonsensical and not want to provide a randomR: would you then leave it undefinded?).
Indeed, the Random class has a fairly narrow "everything fits on the real line" view of the world: not only is the talk about closed intervals ambiguous in general, but so is the talk about uniform distributions on those intervals. That being said, there is an Ord instance for tuples (a lexicographic ordering) and for this case I think it would make the most sense to use that: select an element from the set { x : lo <= x <= hi } -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

On Monday 01 November 2010 19:55:22, Nick Bowler wrote:
On 2010-11-01 19:18 +0100, 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 (you could come up with some definition, but it wouldn't be unique: how would you allow for different ones?[*]; you might decide that having such limits is nonsensical and not want to provide a randomR: would you then leave it undefinded?).
Indeed, the Random class has a fairly narrow "everything fits on the real line" view of the world: not only is the talk about closed intervals ambiguous in general, but so is the talk about uniform distributions on those intervals. That being said, there is an Ord instance for tuples (a lexicographic ordering) and for this case I think it would make the most sense to use that: select an element from the set { x : lo <= x <= hi }
Really bad for lo, hi :: (Int,Integer) lo = (0,0) hi = (3,4) the product (partial) order seems much better to me.

On 2010-11-01 20:09 +0100, Daniel Fischer wrote:
On Monday 01 November 2010 19:55:22, Nick Bowler wrote:
That being said, there is an Ord instance for tuples (a lexicographic ordering) and for this case I think it would make the most sense to use that: select an element from the set { x : lo <= x <= hi }
Really bad for
lo, hi :: (Int,Integer) lo = (0,0) hi = (3,4)
Good point, that's not so hot.
the product (partial) order seems much better to me.
Indeed it does. -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
participants (3)
-
Daniel Fischer
-
Jacek Generowicz
-
Nick Bowler