Olivier Boudry olivier.boudry at gmail.com
Wed May 21 14:31:09 EDT 2008

```On Wed, May 21, 2008 at 11:10 AM, Dmitri O.Kondratiev <dokondr at gmail.com>
wrote:

> But how will 'g1' actually get delivered from 'makeRandomValueST g1' to
> invocation of 'getAny' I don't yet understand!
>
>
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

getAny :: (Random a) => State StdGen a
getAny = do g      <- get
(x,g') <- return \$ random g
put g'
return x

get = State \$ \s -> (s, s) -- copy the state as a return value and pass
state
put s = State \$ \_ -> ((), s) -- return unit, ignore the passed state and
replace it with the state given as parameter.
return a = State \$ \s -> (a, s) -- return given value and pass state.

getAnyNoSugar :: (Random a) => State StdGen a
getAnyNoSugar = (State \$ \s -> (s, s)) >>= \g ->
(State \$ \s -> (random g, s)) >>= \(x,g') ->
(State \$ \_ -> ((), g')) >>
(State \$ \s -> (x, s))

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.

Desugaring the (>>=) and (>>) operators would give you something like this
(I replaced `s` with `y` in the `put` and `return` desugaring and simplified
it):

State \$ \s = let
(g, s') = (\y -> (y,y)) s
((x,g'), s'') = (\y -> (random g, y)) s'
(_, s''') = (\_ -> ((), g')) s''
in (x, s''')

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.

Regards,

Olivier.
-------------- next part --------------
An HTML attachment was scrubbed...