-- Jules, Oliver, thanks! Things are getting clarified, I hope.<br>-- Let me summarize how I now understand getAny operation, please correct me if I am wrong. <br><br>getAny :: (Random a) => State StdGen a<br>getAny = do g <- get<br>
(x,g') <- return $ random g<br> put g'<br> return x<br><br>{--<br>getAny operation may be abbreviated as:<br><br>do { <br>-- 1) x calculation, equivalent to (x,g2) = random g1<br>-- 2) return x ~> State $ \s -> (x,s) -- puts x into State container <br>
<br>Thus getAny returns a State instantiated with a function which is a composition of several binds <<= from the above 'do' block and which calculates 'x'<br>--}<br><br>-- Then we can use this State object (returned by getAny) in a function generating random values such as: <br>
<br>makeRnd :: StdGen -> (Int, StdGen)<br>makeRnd = runState (do<br> y <- getAny<br> return y)<br><br>{-- <br>where:<br><br>y <- getAny <br>return y<br><br>passes a first value from the tuple generated by getAny State function into 'y' and puts 'y' into a new State object.<br>
After that 'runState' in makeRnd extracts from this new State a function parametrized by 'y' value.<br>As a result we get curried 'makeRnd' which we can call with some generator instance and get a random value.<br>
--}<br><br><div class="gmail_quote">On Wed, May 21, 2008 at 10:31 PM, Olivier Boudry <<a href="mailto:olivier.boudry@gmail.com" target="_blank">olivier.boudry@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div>On Wed, May 21, 2008 at 11:10 AM, Dmitri O.Kondratiev <<a href="mailto:dokondr@gmail.com" target="_blank">dokondr@gmail.com</a>> wrote:<br></div><div class="gmail_quote"><div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
But how will 'g1' actually get delivered from 'makeRandomValueST g1' to invocation of 'getAny' I don't yet understand!<div><div></div><br></div></blockquote></div><div><br>It may be easier to understand the state passing if you remove the do notation and replace get, put and return with their definition in the instance declarations (Monad and MonadState).<div>
<br>
<br>getAny :: (Random a) => State StdGen a<br>getAny = do g <- get<br></div><div> (x,g') <- return $ random g<br> put g'<br> return x<br><br></div>get = State $ \s -> (s, s) -- copy the state as a return value and pass state<br>
put s = State $ \_ -> ((), s) -- return unit, ignore the passed state and replace it with the state given as parameter.<br>return a = State $ \s -> (a, s) -- return given value and pass state.<br><br>getAnyNoSugar :: (Random a) => State StdGen a<br>
getAnyNoSugar = (State $ \s -> (s, s)) >>= \g -><br> (State $ \s -> (random g, s)) >>= \(x,g') -><br> (State $ \_ -> ((), g')) >><br> (State $ \s -> (x, s))<br>
<br>The function is still useable this way and the state transformations should be a bit more visible. The first element of the tuple is the value that will be used to call the next function (of type Monad m => a -> m b). The second element of the tuple is the state and the (>>=) operator will handle passing it between actions.<br>
<br>Desugaring the (>>=) and (>>) operators would give you something like this (I replaced `s` with `y` in the `put` and `return` desugaring and simplified it):<br><br>State $ \s = let<br> (g, s') = (\y -> (y,y)) s<br>
((x,g'), s'') = (\y -> (random g, y)) s'<br> (_, s''') = (\_ -> ((), g')) s''<br> in (x, s''')<br><br>Which is explict state passing between function calls. Extract the State using `runState`, run it with an initial state and it should give you the expected result.<br>
<br>Regards,<br><br>Olivier.<br></div></div>
</blockquote></div><br><br clear="all"><br>-- <br>Dmitri O. Kondratiev<br><a href="mailto:dokondr@gmail.com" target="_blank">dokondr@gmail.com</a><br><a href="http://www.geocities.com/dkondr" target="_blank">http://www.geocities.com/dkondr</a>