-- 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
--   <a>https://github.com/pwrobinson/dice-entropy-conduit#readme</a>
@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 <tt>k</tt> rolls of an <tt>n</tt> 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
--   <tt>[0,n-1]</tt>, for a given <tt>n &lt;= 2^55</tt>. This conduit
--   needs to be attached to an entropy source such as
--   <a>systemEntropy</a>.
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
--   <a>systemEntropy</a>.
randomRs :: (Int, Int) -> Conduit Word8 IO Int

-- | A source of entropy. By default, we use the <a>getEntropy</a> function
--   from the entropy package, see <a>systemEntropy</a>.
--   
--   <i>Warning:</i> 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:
--   <tt>myEntropySrc $$ Data.Conduit.List.map id =$= myConduit</tt>
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 <tt>n</tt>-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 <tt>ln(n) /
--   ln(2)</tt> (for a range of size <tt>n</tt>).
--   
--   The implementation exposes streams of random values as conduits, see
--   <a>diceRolls</a> and <a>randomRs</a>. We also provide IO wrappers
--   around these functions, see <a>getDiceRolls</a> and
--   <a>getRandomRs</a>. The conduit interface allows us to use a specific
--   entropy source, which has type <tt>Producer</tt> <a>IO</a>
--   <a>Word</a>.
--   
--   <i>Usage:</i>
--   
--   If we wanted to use the system-specific entropy source
--   (<a>systemEntropy</a>) to produce 10 dice rolls of a 6-sided dice
--   (i.e. range [0,5]), we could write:
--   
--   <pre>
--   &gt; systemEntropy $$ diceRolls 6 =$= CL.take 10
--   [5,1,3,3,0,5,3,2,2,1]
--   </pre>
--   
--   The function <tt>testPerformance</tt> yields the actual number of
--   consumed random bits:
--   
--   <pre>
--   &gt; 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
--   </pre>
module System.Random.Dice

-- | Produces a stream of random integer values in the range
--   <tt>[0,n-1]</tt>, for a given <tt>n &lt;= 2^55</tt>. This conduit
--   needs to be attached to an entropy source such as
--   <a>systemEntropy</a>.
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
--   <a>systemEntropy</a>.
randomRs :: (Int, Int) -> Conduit Word8 IO Int

-- | Generates <tt>k</tt> rolls of an <tt>n</tt> 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 <a>getEntropy</a> function
--   from the entropy package, see <a>systemEntropy</a>.
--   
--   <i>Warning:</i> 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:
--   <tt>myEntropySrc $$ Data.Conduit.List.map id =$= myConduit</tt>
systemEntropy :: Producer IO Word8
