Every wanted to roll the dice in Haskell? Let’s say you have a data type like
How do you generate a random
Number value? There are several ways to do it, usually in an
IO context, obviously. In order to use it in a
common monad transformer stack, the primitives of the
MonadRandom type class come to my mind. So it would be most convenient to get a
random value using
getRandom. Anyway, as much fun as rolling the dice is, let’s derive a solution working for all bounded Enums.
Anyway, import Control.Monad.Random as we want to use
getRandom of the
MonadRandom class which looks like:
1 2 3 4 5 6 7 8
randomR needs to be able to provide a random
Number value in the specified interval, given a random number generator. So the idea is about mapping the Enum values to
and deriving a random Enum value from a randomly generated number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
While we still used the explicit
Number interval values in 1), we get a more general solution in 2) using the fact that we had auto-derived an instance of
Number and thus have
maxBound at our disposal.
At last, we can generate a random
Anyway, our generated
Number values are uniformly distributed, every value occurs with equal probability. What if you want to tamper with the die at little, e.g.
when your opponent throws the dice they should not get a
Six quite so often. You could do that providing a respective
Random instance for a newtype wrapper:
1 2 3 4 5 6 7 8 9 10 11
rollDice function then looks so inconspicuous, your opponent might not even notice:
1 2 3 4 5 6 7 8 9
They might actually think that they are just unlucky:
1 2 3 4
You can find the source here.