module System.Random.Stream
(
Stream (..)
, mkStream
)
where
import Data.Binary.Get (runGetState, getWordhost)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Internal as LI
import System.IO.Unsafe (unsafeInterleaveIO, unsafePerformIO)
import System.Random (RandomGen(..))
import System.Random.URandom (urandom)
newtype Stream = Stream L.ByteString
defaultChunkSize :: Int
defaultChunkSize = 128 LI.chunkOverhead
mkStream :: Stream
mkStream = Stream $ unsafePerformIO $ pseudoBytesStream defaultChunkSize
pseudoBytesStream :: Int -> IO L.ByteString
pseudoBytesStream n = lazyGet
where
lazyGet = unsafeInterleaveIO loop
loop = do
c <- urandom n
cs <- lazyGet
return $ LI.Chunk c cs
instance RandomGen Stream where
next = randomInt
split = error "System.Random.Stream: split not implemented"
randomInt :: Stream -> (Int, Stream)
randomInt (Stream s) = (fromIntegral i, Stream s')
where
(i, s', _) = runGetState getWordhost s 0