2008/5/22 Olivier Boudry <olivier.boudry@gmail.com>:
On Wed, May 21, 2008 at 6:19 PM, Dmitri O.Kondratiev <dokondr@gmail.com> wrote:
-- 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)
You can simplify this:
do y <- m return y
is equivalent to
`do m`
or `m`
According to Monad Laws.
So you could write the same code as: makeRnd = runState getAny
In that case, the use of the State Monad is not really interesting as you just replaced a call to `random g` with a call to `runState getAny g`. The State Monad is interesting if you have more than one action in the first argument of the `runState` function because the state passing will only work in a single `State s a`.
Incidentally, since random has type (Random a, RandomGen g) => g -> (a,g), getAny could have been defined simply as getAny = State random It may be helpful to prove that this definition is equivalent to the one given in the original post. Oh, and here's a super-simple example using the state monad: randR :: (Random a) => (a,a) -> State StdGen a randR range = State (randomR range) twoDice :: State StdGen Int twoDice = do d1 <- randR (1,6) d2 <- randR (1,6) return (d1 + d2) nDice :: Int -> State StdGen Int nDice n | n < 1 = return 0 nDice n = do x <- randR (1,6) y <- rollN (n - 1) return (x + y) Because State StdGen is a monad, you can rewrite nDice without explicit recursion using foldM: nDice n = foldM (\sum m -> liftM (sum+) m) 0 $ take n $ repeat (randR (1,6)) -- Dave Menendez <dave@zednenem.com> <http://www.eyrie.org/~zednenem/>