[Haskell-beginners] Randomness woes

Stephen Blackheath [to Haskell-Beginners] mutilating.cauliflowers.stephen at blacksapphire.com
Sun Jan 10 16:03:46 EST 2010

Erlend - see below...

Erlend Hamberg wrote:
> ...
> I have two concerns about my architecture. The first one is that I have 
> several “layers” of randomness: The main function will call makePopulation 
> which in turn will call rouletteSelect and reproduce. The latter will then 
> call mutate, which also involves randomness. As can be seen above, I have 
> rewritten mutate to take a list of booleans so that I can use getRandomRs in 
> reproduce instead of having to have yet another layer of
>   g <- getSplit
>   let genome' = evalRand (mutate genome) g
> Handling the random generator explicitly like this feels a bit ugly. Or is 
> this okay?

If you replace the code above with just

    mutate genome

then it will pass the random number generator 'through' mutate and on
completion the RNG in the calling context will be changed to what
'mutate' returned.  Since you're not using multiple threads, this should
be correct for your application, but it's not quite equivalent to your
code, because you're not actually splitting the RNG.  If you really need
to split it, you could write yourself a helper function like this:

splitting :: RandomGen g => Rand g a -> Rand g a
splitting code = do
    g <- getSplit
    return $ evalRand code g

Then say

    splitting $ mutate genome

> Calling getSplit and then evalRand recursively is what I do in makePopulation, 
> to make a new population. I would greatly appreciate comments on how this 
> “should” be done. I realise that I could just get a list of random numbers in 
> makePopulation and then use this as a source of randomness for the called 
> functions, but I fear that this would just lead to inelegant code managing 
> (chunks of) this list.

Gokhan San answered this better than I was going to.


More information about the Beginners mailing list