1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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)
|