frederik at a5.repetae.net
Fri Jan 5 05:21:21 EST 2007
I'm having trouble using RandomGen with external tools (e.g. libraries
written in C).
StdGen has a nice function:
mkStdGen :: Int -> StdGen
Using this, I can write an FFI wrapper ending with type:
(StdGen -> (a, StdGen))
by using the StdGen to generate an Int, and then using that to seed a
foreign random number generator within C, and then at the end of the C
function reading a final random number, passing it back to Haskell,
and passing it to mkStdGen. This will always have the right semantics,
However, there are several problems:
- It only works for StdGen, not arbitrary instances of RandomGen
- It "shrinks" my whole random state into an Int - so I might have
1024 bits of state in my random number generator within C, and within
Haskell, but when I move between the two, everything is truncated to
32 bits. This is problematic in some applications, and as computers
become faster it will be more of a concern.
Thus, I suggest a new member of class RandomGen:
mkRandomGen :: [Int] -> g
It is similar to mkStdGen, but it takes a list of Int's so that users
who want to save more bits of state across conversions can do so.
Also, being a member of the RandomGen class, it can be depended on in
more situations than mkStdGen.
There is a question of backward compatibility with existing RandomGen
instances. I think the best thing to do is provide a default
definition for mkRandomGen which is an error or 'undefined'. This way,
legacy code will still compile, but libraries which define RandomGen
instances just won't work with new code which tries to call
mkRandomGen. I don't imagine that there are many such libraries, and
besides they wouldn't have been useful in any case if the code in
question had been restricted to mkStdGen as it is currently.
Hope I'm not missing some previous discussion.
More information about the Libraries