module Data.Random.Source
( MonadRandom(..)
, RandomSource(..)
) where
import Data.Word
import Data.Bits
import Data.List
import Data.Random.Internal.Words
class Monad m => MonadRandom m where
getRandomBytes :: Int -> m [Word8]
getRandomBytes n
| n .&. 7 == 0
= do
let wc = n `shiftR` 3
ws <- getRandomWords wc
return (concatMap wordToBytes ws)
| otherwise
= do
let wc = (n `shiftR` 3) + 1
ws <- getRandomWords wc
return . take n . concatMap wordToBytes $ ws
getRandomWords :: Int -> m [Word64]
getRandomWords n = do
bs <- getRandomBytes (n `shiftL` 3)
return (bytesToWords bs)
class Monad m => RandomSource m s where
getRandomBytesFrom :: s -> Int -> m [Word8]
getRandomBytesFrom src n
| n .&. 7 == 0
= do
let wc = n `shiftR` 3
ws <- getRandomWordsFrom src wc
return (concatMap wordToBytes ws)
| otherwise
= do
let wc = (n `shiftR` 3) + 1
ws <- getRandomWordsFrom src wc
return . take n . concatMap wordToBytes $ ws
getRandomWordsFrom :: s -> Int -> m [Word64]
getRandomWordsFrom src n = do
bs <- getRandomBytesFrom src (n `shiftL` 3)
return (bytesToWords bs)
instance Monad m => RandomSource m (Int -> m [Word8]) where
getRandomBytesFrom = id
instance Monad m => RandomSource m (Int -> m [Word64]) where
getRandomWordsFrom = id