# Main die roll type

type DieRoll = EventM IntSource

A type synonym for events with an integer outcome (i.e. all standard die rolls).

The `Num`

instance for `EventM Int`

allows you to add the results of two die
rolls, or subtract them (if it helps, `(+) = liftA2 (+)`

).

Multiplication works as follows. `d * e`

evaluates the first die roll,
then sums that many rolls of the second. So `2 * d6`

rolls two d6 and adds
the outcomes. However, this definition means that `d6 * 2`

rolls one d6,
then effectively scales the result by 2. And `d6 * d4`

rolls one d6, then
rolls that number of `d4`

, adding their results together. The simple rule
when one of the terms is a constant is: use the constant on the left-hand
side to get more dice, and use the constant on the right-hand side to scale
the result.

roll :: DieRoll -> IO IntSource

A nice synonym for `enact`

: actually rolls the die and produces a single result according to the probabilities
in the `EventM a`

parameter.

# Dice definitions

Makes a die that has an equal chance of achieving the numbers 1 through the
number given. `d 4`

has an equal chance of producing the outcomes 1, 2, 3 and
4, `d 1`

is equivalent to `return 1`

(a certain result of 1), and
`d`

is undefined for any number below 1. For convenience, all the standard dice are
provided, e.g. `d6 = d 6`

.

Makes a die that has an equal chance of achieving the numbers 0 through
the one less than the number given. `z 4`

has an equal chance of producing
the outcomes 0, 1, 2 and 3, while `z 1`

is equivalent to `return 0`

(a
certain result of 0), and `z`

is undefined for any number below 1. For
convenience, several standard dice that can be interpreted with a lower
result of 0 are provided, e.g. `z10 = z 10`

.

# Dice helper functions

rerollOn :: DieRoll -> [Int] -> DieRollSource

Rerolls the die when the specified outcome(s) occur. This has the effect of removing the outcomes from the set of outcomes and rescaling all the other probabilities linearly to sum to 1. For example:

d6 `rerollOn` [5,6] == d4 chancePred (== 12) ((2*d6) `rerollOn` [7]) == 1/30

With the latter example, the standard chance of 12 on 2d6 is 1/36, which
is rescaled by 36/30, the reciprocal of the chance of *not* hitting
a 7.