diff options
Diffstat (limited to 'Haskell-book/23/RandomExample/src')
| -rw-r--r-- | Haskell-book/23/RandomExample/src/RandomExample.hs | 31 | ||||
| -rw-r--r-- | Haskell-book/23/RandomExample/src/RandomExample2.hs | 54 |
2 files changed, 85 insertions, 0 deletions
diff --git a/Haskell-book/23/RandomExample/src/RandomExample.hs b/Haskell-book/23/RandomExample/src/RandomExample.hs new file mode 100644 index 0000000..deaa449 --- /dev/null +++ b/Haskell-book/23/RandomExample/src/RandomExample.hs @@ -0,0 +1,31 @@ +module RandomExample where + +import System.Random + +data Die = DieOne + | DieTwo + | DieThree + | DieFour + | DieFive + | DieSix + deriving (Eq, Show) + +intToDie :: Int -> Die +intToDie n = + case n of + 1 -> DieOne + 2 -> DieTwo + 3 -> DieThree + 4 -> DieFour + 5 -> DieFive + 6 -> DieSix + -- Use 'error' __extermely_ sparingly + x -> error $ "intToDie got non 1-6 integer: " ++ show x + +rollDieThreeTimes :: (Die, Die, Die) +rollDieThreeTimes = do + let s = mkStdGen 0 + (d1, s1) = randomR (1, 6) s + (d2, s2) = randomR (1, 6) s1 + (d3, _) = randomR (1, 6) s2 + (intToDie d1, intToDie d2, intToDie d3) diff --git a/Haskell-book/23/RandomExample/src/RandomExample2.hs b/Haskell-book/23/RandomExample/src/RandomExample2.hs new file mode 100644 index 0000000..6fbd821 --- /dev/null +++ b/Haskell-book/23/RandomExample/src/RandomExample2.hs @@ -0,0 +1,54 @@ +module RandomExample2 where + +import Control.Applicative (liftA3) +import Control.Monad (replicateM) +import Control.Monad.Trans.State +import System.Random +import RandomExample + +rollDie :: State StdGen Die +rollDie = state $ do + (n, s) <- randomR (1, 6) + return (intToDie n, s) + +rollDie' :: State StdGen Die +rollDie' = intToDie <$> state (randomR (1, 6)) + +rollDieThreeTimes' :: State StdGen (Die, Die, Die) +rollDieThreeTimes' = liftA3 (,,) rollDie rollDie rollDie + +infiniteDie :: State StdGen [Die] +infiniteDie = repeat <$> rollDie + +nDie :: Int -> State StdGen [Die] +nDie n = replicateM n rollDie + +rollsToGetTwenty :: StdGen -> Int +rollsToGetTwenty g = go 0 0 g + where + go :: Int -> Int -> StdGen -> Int + go sum count gen + | sum >= 20 = count + | otherwise = + let (die, nextGen) = randomR (1, 6) gen + in go (sum + die) (count + 1) nextGen + +rollsToGetN :: Int -> StdGen -> Int +rollsToGetN limit g = go 0 0 g + where + go :: Int -> Int -> StdGen -> Int + go sum count gen + | sum >= limit = count + | otherwise = + let (die, nextGen) = randomR (1, 6) gen + in go (sum + die) (count + 1) nextGen + +rollsCountLogged :: Int -> StdGen -> (Int, [Die]) +rollsCountLogged limit g = go 0 0 g [] + where + go :: Int -> Int -> StdGen -> [Die] -> (Int, [Die]) + go sum count gen dies + | sum >= limit = (count, dies) + | otherwise = + let (die, nextGen) = randomR (1, 6) gen + in go (sum + die) (count + 1) nextGen ((intToDie die) : dies) |
