-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Cryptographically secure n-sided dice via rejection sampling
--   
--   Please see the README on GitHub at
--   https://github.com/pwrobinson/dice-entropy-conduit#readme
@package dice-entropy-conduit
@version 1.0.0.3

module System.Random.Dice.Internal

-- | Converts a number to its base-2 representation (as a list of bits) and
--   prepends zeros to ensure the minimal size.
integralToBits :: (Integral n, Integral m) => Int -> n -> [m]

-- | Convert a list of bits to an integral
bitsToIntegral :: Integral n => [n] -> n
extendIntegralWithBits :: Integral n => n -> [n] -> n

-- | Upper bound on the number of sides that a random dice can have.
upperBound :: Word64

-- | Generates k rolls of an n sided dice.
getDiceRolls :: Int -> Int -> IO [Int]

-- | Generates a list of random integer values in the specified range.
getRandomRs :: (Int, Int) -> Int -> IO [Int]

-- | Produces a stream of random integer values in the range
--   [0,n-1], for a given n <= 2^55. This conduit
--   needs to be attached to an entropy source such as
--   systemEntropy.
diceRolls :: Int -> Conduit Word8 IO Int

-- | Produces a stream of random integer values within a range. This
--   conduit needs to be attached to an entropy source such as
--   systemEntropy.
randomRs :: (Int, Int) -> Conduit Word8 IO Int

-- | A source of entropy. By default, we use the getEntropy function
--   from the entropy package, see systemEntropy.
--   
--   Warning: When combining a source of entropy with other
--   conduits, it is important that there is no "backflow" due to leftover
--   values that are being returned to the source from the conduit. This
--   can be done by fusing the conduit with the identity map, e.g:
--   myEntropySrc $$ Data.Conduit.List.map id =$= myConduit
systemEntropy :: Producer IO Word8

-- | Internal function. Should not be invoked directly.
dRoll :: Word64 -> Word64 -> Word64 -> Int -> Conduit Word8 IO (Int, Int)

-- | 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

-- | Produces a stream of random integer values in the range
--   [0,n-1], for a given n <= 2^55. This conduit
--   needs to be attached to an entropy source such as
--   systemEntropy.
diceRolls :: Int -> Conduit Word8 IO Int

-- | Produces a stream of random integer values within a range. This
--   conduit needs to be attached to an entropy source such as
--   systemEntropy.
randomRs :: (Int, Int) -> Conduit Word8 IO Int

-- | Generates k rolls of an n sided dice.
getDiceRolls :: Int -> Int -> IO [Int]

-- | Generates a list of random integer values in the specified range.
getRandomRs :: (Int, Int) -> Int -> IO [Int]

-- | A source of entropy. By default, we use the getEntropy function
--   from the entropy package, see systemEntropy.
--   
--   Warning: When combining a source of entropy with other
--   conduits, it is important that there is no "backflow" due to leftover
--   values that are being returned to the source from the conduit. This
--   can be done by fusing the conduit with the identity map, e.g:
--   myEntropySrc $$ Data.Conduit.List.map id =$= myConduit
systemEntropy :: Producer IO Word8
