[Haskell-cafe] State Monad - using the updated state
pbeadling at mail2web.com
Wed Jan 7 20:52:05 EST 2009
I¹m a newbie looking to get my head around using the State Monad for random
number generation. I¹ve written non-monad code that achieves this no
problem. When attempting to use the state monad I can get what I know to be
the correct initial value and state, but can¹t figure out for the life of me
how to then increment it without binding more calls there and then. Doing
several contiguous calls is not what I want to do here and the examples
I¹ve read all show this (using something like liftM2 (,) myRandom myRandom).
I want to be able to do:
< a whole load of other stuff >
Get the next number as defined by the updated state in the first call
<some more stuff>
Get another number, and so on.
I get the first number fine, but am lost at how to get the second, third,
forth etc without binding there and then. I just want each number one at a
time where and when I want it, rather than saying give 1,2,10 or even n¹
numbers now. I¹m sure it¹s blindly obvious!
Note: I¹m not using Haskell¹s built in Random functionality (nor is that an
option), I¹ll spare the details of the method I¹m using (NRC¹s ranq1) as I
know it works for the non-Monad case, and it¹s irrelevent to the question.
So the code is:
ranq1 :: Word64 -> ( Double, Word64 )
ranq1 state = ( output, newState )
newState = ranq1Increment state
output = convert_to_double newState
ranq1Init :: Word64 -> Word64
ranq1Init = convert_to_word64 . ranq1Increment . xor_v_init
-- I¹ll leave the detail of how ranq1Increment works out for brevity. I
know this bit works fine. Same goes for the init function it¹s just
providing an initial state.
-- The Monad State Attempt
getRanq1 :: State Word64 Double
getRanq1 = do
state <- get
let ( randDouble, newState ) = ranq1 state
_________ And then in my main _________
-- 124353542542 is just an arbitrary seed
main :: IO()
main = do
let x = evalState getRanq1 (ranq1Init 124353542542)
As I said this works fine; x gives me the correct first value for this
sequence, but how do I then get the second and third without writing the
giveMeTenRandoms style function? I guess what I want is a next() type
function, imperatively speaking.
Many thanks for any help,
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe