summaryrefslogtreecommitdiff
path: root/Haskell-book/23/RandomExample/src
diff options
context:
space:
mode:
Diffstat (limited to 'Haskell-book/23/RandomExample/src')
-rw-r--r--Haskell-book/23/RandomExample/src/RandomExample.hs31
-rw-r--r--Haskell-book/23/RandomExample/src/RandomExample2.hs54
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)