{-# LANGUAGE Rank2Types #-} ----------------------------------------------------------------------------- -- | -- Module : System.Random.Dice -- Copyright : Peter Robinson 2014 -- License : LGPL -- -- Maintainer : Peter Robinson -- Stability : experimental -- Portability : portable -- -- This module implements an @n@-sided dice and provides sampling from a given -- integer range. -- The algorithm uses rejection sampling and attempts to keep the total number -- of used random bits as close as possible to the information theoretic lower -- bound of @ln(n) / ln(2)@ (for a range of size @n@). -- -- The implementation exposes streams of random values as conduits, see -- 'diceRolls' and 'randomRs'. We also provide IO wrappers around these -- functions, see 'getDiceRolls' and 'getRandomRs'. -- The conduit interface allows us to use a specific entropy source, which has -- type 'Producer' 'IO' 'Word'. -- -- /Usage:/ -- -- If we wanted to use the system-specific entropy source ('systemEntropy') to -- produce 10 dice rolls of a 6-sided dice (i.e. range [0,5]), we could write: -- -- > > systemEntropy $$ diceRolls 6 =$= CL.take 10 -- > [5,1,3,3,0,5,3,2,2,1] -- -- The function 'testPerformance' yields the actual number of consumed random -- bits: -- -- > > testPerformance 12 10000 -- > Generated 10000 random samples in range [0,11] -- > Average number of bits used: 3.5904 -- > Entropy lower bound on the number of required bits: 3.5849625007211565 -- > Performance ratio: 1.0015167520658164 -- ----------------------------------------------------------------------------- module System.Random.Dice( diceRolls , randomRs , getDiceRolls , getRandomRs , testPerformance , systemEntropy ) where import System.Random.Dice.Internal