-- Jules, Oliver, thanks! Things are getting clarified, I hope. -- Let me summarize how I now understand getAny operation, please correct me if I am wrong.
getAny :: (Random a) => State StdGen a getAny = do g <- get (x,g') <- return $ random g put g' return x {-- getAny operation may be abbreviated as: do { -- 1) x calculation, equivalent to (x,g2) = random g1 -- 2) return x ~> State $ \s -> (x,s) -- puts x into State container 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' --} -- Then we can use this State object (returned by getAny) in a function generating random values such as: makeRnd :: StdGen -> (Int, StdGen) makeRnd = runState (do y <- getAny return y) {-- where: y <- getAny return y passes a first value from the tuple generated by getAny State function into 'y' and puts 'y' into a new State object. After that 'runState' in makeRnd extracts from this new State a function parametrized by 'y' value. As a result we get curried 'makeRnd' which we can call with some generator instance and get a random value. --} On Wed, May 21, 2008 at 10:31 PM, Olivier Boudry <[EMAIL PROTECTED]> wrote: > On Wed, May 21, 2008 at 11:10 AM, Dmitri O.Kondratiev <[EMAIL PROTECTED]> > 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 > instance declarations (Monad and MonadState). > > 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. > -- Dmitri O. Kondratiev [EMAIL PROTECTED] http://www.geocities.com/dkondr
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe