-- MonadicRandomGenerator.hs (Learn You a Haskell for Great G | -- DesugaredMonadicRandomGenerator.hs (Learn You a Haskell fo import System.Random import System.Random import Control.Monad.State import Control.Monad.State randomSt :: (RandomGen g, Random a) => State g a randomSt :: (RandomGen g, Random a) => State g a -- The following line was wrong in the book: | randomSt = -- randomSt = State random | get >>= randomSt = do | \gen -> gen <- get | let (value,nextGen) = random gen let (value,nextGen) = random gen | in put nextGen | put nextGen >> return value | return value randomSt1 = (runState randomSt (mkStdGen 1)) :: (Int,StdGen) randomSt1 = (runState randomSt (mkStdGen 1)) :: (Int,StdGen) randomSt2 = (runState randomSt (mkStdGen 2)) :: (Float,StdGen randomSt2 = (runState randomSt (mkStdGen 2)) :: (Float,StdGen threeCoins :: State StdGen (Bool,Bool,Bool) | threeCoins :: State StdGen (Bool,Bool,Bool) threeCoins = do | threeCoins = a <- randomSt | randomSt >>= b <- randomSt | \a -> randomSt >>= c <- randomSt | \b -> randomSt >>= return (a,b,c) | \c -> return (a,b,c) threeCoins1 = runState threeCoins (mkStdGen 33) threeCoins1 = runState threeCoins (mkStdGen 33) threeCoins2 = runState threeCoins (mkStdGen 2) threeCoins2 = runState threeCoins (mkStdGen 2) -- rollDie and rollNDice are not explained in the book LYAHFG -- rollDie and rollNDice are not explained in the book LYAHFG -- But these functions are interesting and complementary: -- But these functions are interesting and complementary: rollDie :: State StdGen Int rollDie :: State StdGen Int rollDie = do | rollDie = generator <- get | get >>= let (value, newGenerator) = randomR (1,6) generator | \generator -> put newGenerator | let (value, newGenerator) = randomR (1,6) generator return value | in > put newGenerator >> > return value rollDie1 = runState rollDie (mkStdGen 1) rollDie1 = runState rollDie (mkStdGen 1) rollDie2 = runState rollDie (mkStdGen 2) rollDie2 = runState rollDie (mkStdGen 2) rollNDice :: Int -> State StdGen [Int] rollNDice :: Int -> State StdGen [Int] rollNDice 0 = do | rollNDice 0 = return [] return [] | rollNDice n = rollNDice n = do | rollDie >>= value <- rollDie | \value -> rollNDice (n-1) >>= list <- rollNDice (n-1) | \list -> return (value:list) return (value:list) < rollNDice1 = runState (rollNDice 10) (mkStdGen 1) rollNDice1 = runState (rollNDice 10) (mkStdGen 1) rollNDice2 = runState (rollNDice 20) (mkStdGen 2) | rollNDice2 = runState (rollNDice 20) (mkStdGen 2)