random-fu-0.0.2.1: src/Data/Random/Source.hs
{-
- ``Data/Random/Source''
-}
{-# LANGUAGE
MultiParamTypeClasses, FlexibleInstances
#-}
module Data.Random.Source
( MonadRandom(..)
, RandomSource(..)
) where
import Data.Word
import Control.Monad
import Data.Random.Internal.Words
-- |A typeclass for monads with a chosen source of entropy. For example,
-- 'RVar' is such a monad - the source from which it is (eventually) sampled
-- is the only source from which a random variable is permitted to draw, so
-- when directly requesting entropy for a random variable these functions
-- are used.
--
-- The minimal definition is either 'getRandomByte' or 'getRandomWord'.
-- 'getRandomDouble' is defaulted in terms of 'getRandomWord'.
class Monad m => MonadRandom m where
-- |Get a random uniformly-distributed byte.
getRandomByte :: m Word8
getRandomByte = do
word <- getRandomWord
return (fromIntegral word)
-- |Get a random 'Word64' uniformly-distributed over the full range of the type.
getRandomWord :: m Word64
getRandomWord = do
b0 <- getRandomByte
b1 <- getRandomByte
b2 <- getRandomByte
b3 <- getRandomByte
b4 <- getRandomByte
b5 <- getRandomByte
b6 <- getRandomByte
b7 <- getRandomByte
return (buildWord b0 b1 b2 b3 b4 b5 b6 b7)
-- |Get a random 'Double' uniformly-distributed over the interval [0,1)
getRandomDouble :: m Double
getRandomDouble = do
word <- getRandomWord
return (wordToDouble word)
-- |A source of entropy which can be used in the given monad.
--
-- The minimal definition is either 'getRandomByteFrom' or 'getRandomWordFrom'.
-- 'getRandomDoubleFrom' is defaulted in terms of 'getRandomWordFrom'
class Monad m => RandomSource m s where
-- |Get a random uniformly-distributed byte.
getRandomByteFrom :: s -> m Word8
getRandomByteFrom src = do
word <- getRandomWordFrom src
return (fromIntegral word)
-- |Get a random 'Word64' uniformly-distributed over the full range of the type.
getRandomWordFrom :: s -> m Word64
getRandomWordFrom src = do
b0 <- getRandomByteFrom src
b1 <- getRandomByteFrom src
b2 <- getRandomByteFrom src
b3 <- getRandomByteFrom src
b4 <- getRandomByteFrom src
b5 <- getRandomByteFrom src
b6 <- getRandomByteFrom src
b7 <- getRandomByteFrom src
return (buildWord b0 b1 b2 b3 b4 b5 b6 b7)
-- |Get a random 'Double' uniformly-distributed over the interval [0,1)
getRandomDoubleFrom :: s -> m Double
getRandomDoubleFrom src = do
word <- getRandomWordFrom src
return (wordToDouble word)
instance Monad m => RandomSource m (m Word8) where
getRandomByteFrom = id
instance Monad m => RandomSource m (m Word64) where
getRandomWordFrom = id