## Contents

### Random Number Generation

Exercises
1. Roll two dice! With `sumTwoDice` that is :-) . Use `fst` to extract the result.
2. Write a function `rollNDice :: Int -> Seed -> ([Int],Seed)` that rolls dice n times and returns a list of the n results. Extra: If you know about infinite lists, use `unfoldr` and `take` to get the result list (but without seed this time).
3. Reimplement `Seed` and `rollDie` with `StdGen` and `random` from System.Random.
4. Now that you have random numbers, do some statistical experiments with the help of `rollNDice`. For example, do a sanity check that `rollDie` is not skewed and returns each number with equal likelihood. How is the sum of pips of a double dice roll distributed? The difference? And triple rolls?

2. Using ` randomNext `, `Seed` and `rollDie` as defined in the chapter:

```rollNDice :: Int -> Seed -> ([Int], Seed)
rollNDice 0 seed = ([], seed)
rollNDice n seed = let (die,  seed0) = rollDie seed
(rest, seed1) = rollNDice (n-1) seed0
in ((die : rest) ,
seed1)
```

The function gains the first die and seed and then recursively calls itself to roll N number of die which, once `RollNDice` reaches the base case, in turn builds up a list of die. The function then returns the list of die and the final seed that was passed to the base case, ` rollNDice 0 seed = ([], seed)`.

3. We use mkStdGen to get the computer's random number generator and we give it an arbitrary number, 232. Firstly with `import System.Random` at the top of your file:

```type Seed = StdGen
```
```rollDie1 :: Seed -> (Int, Seed)
rollDie1 seed = randomR (1,6) seed
```

In Prelude:

```Main> rollDie1 (mkStdGen 232)
(3,1017593109 40692)
```

### Threading the State with bind

Exercises
1. Implement `rollNDice :: Int -> Random [Int]` from the previous subsection with `>>=` and `return`.

1. You have seen everything below the definition of `(>>==)` before. So everything up to that point is just there to set everything up. I've named >>= `>>==` and return `return1` because this chapter uses bind and return to deal with random numbers specifically; whereas the real bind and return are more generalised and thus do not work for reasons that are somewhere over -----------------> there. At least it works; what more do you want from me? Blood?

With `import System.Random` at the top of your file:

```type Seed = StdGen
type Random1 a = Seed -> (a, Seed)

rollDie :: Random1 Int
rollDie seed = randomR (1,6) seed

(>>==) :: Random1 a -> (a -> Random1 b) -> Random1 b
(>>==) m g = \seed0 ->
let (result1, seed1) = m seed0
(result2, seed2) = (g result1) seed1
in (result2, seed2)

return1 :: a -> Random1 a
return1 x = \seed0 -> (x, seed0)

rollNDice1 :: Int -> Random1 [Int]
rollNDice1 0 = return1 []
rollNDice1 n = rollDie >>== (\d1 -> rollNDice1 (n-1) >>== (\rest -> return1 (d1 : rest)))
```

In prelude:

```
*Main> rollNDice1 20 (mkStdGen 231)
([4,3,1,1,2,3,5,4,2,5,6,4,6,2,4,5,6,5,1,5],1927676552 238604751)
```

In case you're wondering: You pass `(mkStdGen 232111)` to rollNDice1 because `rollNDice 20` on its own only creates a `Random1 [Int]`; you need to pass the newly formed `Random1 [Int]` a seed, in the form of `(mkStdGen 242)`, to get it shooting out random numbers.

### Input/Output needs bind

Exercises
1. Write a function `putString :: String -> IO ()` that outputs a sequence of characters with the help of `putChar`.
2. The program loop :: IO () loop = return () >> loop loops forever whereas loopX :: IO () loopX = putChar 'X' >> loopX prints an infinite sequence `XXXXXX...` of `X`-s. Clearly, a user can easily distinguish them by looking on the screen. However, show that the model `IO a = World -> (a, World)` gives the same denotation ⊥ for both. This means that we have to abandon this model as possible semantics for `IO a`.

1.

```putString :: String -> IO ()
putString [] = putChar '\n'
putString (s:xs) = putChar s >> putString xs
```

Correct the definition for `(>>=)` to take the State constructor into consideration. You'll need to use pattern matching to remove the State constructor.
```(State a) >>= f = State \$ \s -> let (a',s') = a s
1. Slightly rewrite your definition of (>>=) to use `runState` instead of pattern-matching on `State`
```a >>= f = State \$ \s -> let (a',s') = runState a s