module Data.Random.Source.StdGen where
import Data.Random.Internal.Words
import Data.Random.Source
import System.Random
import Control.Monad.State
import qualified Control.Monad.ST.Strict as S
import qualified Control.Monad.State.Strict as S
import Data.StateRef
import Data.Word
instance (Monad m1, ModifyRef (Ref m2 StdGen) m1 StdGen) => RandomSource m1 (Ref m2 StdGen) where
getRandomByteFrom = getRandomByteFromRandomGenRef
getRandomWordFrom = getRandomWordFromRandomGenRef
getRandomDoubleFrom = getRandomDoubleFromRandomGenRef
instance (Monad m, ModifyRef (IORef StdGen) m StdGen) => RandomSource m (IORef StdGen) where
getRandomByteFrom = getRandomByteFromRandomGenRef
getRandomWordFrom = getRandomWordFromRandomGenRef
getRandomDoubleFrom = getRandomDoubleFromRandomGenRef
instance (Monad m, ModifyRef (TVar StdGen) m StdGen) => RandomSource m (TVar StdGen) where
getRandomByteFrom = getRandomByteFromRandomGenRef
getRandomWordFrom = getRandomWordFromRandomGenRef
getRandomDoubleFrom = getRandomDoubleFromRandomGenRef
instance (Monad m, ModifyRef (STRef s StdGen) m StdGen) => RandomSource m (STRef s StdGen) where
getRandomByteFrom = getRandomByteFromRandomGenRef
getRandomWordFrom = getRandomWordFromRandomGenRef
getRandomDoubleFrom = getRandomDoubleFromRandomGenRef
getRandomByteFromStdGenIO :: IO Word8
getRandomByteFromStdGenIO = do
int <- randomRIO (0, 255) :: IO Int
return (fromIntegral int)
getRandomWordFromStdGenIO :: IO Word64
getRandomWordFromStdGenIO = do
int <- randomRIO (0, 0xffffffffffffffff)
return (fromInteger int)
getRandomDoubleFromStdGenIO :: IO Double
getRandomDoubleFromStdGenIO = liftM wordToDouble getRandomWordFromStdGenIO
getRandomByteFromRandomGenRef :: (Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> m Word8
getRandomByteFromRandomGenRef g = atomicModifyReference g (swap . randomR (0,255))
where
swap :: (Int, a) -> (a, Word8)
swap (a,b) = (b,fromIntegral a)
getRandomWordFromRandomGenRef :: (Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> m Word64
getRandomWordFromRandomGenRef g = atomicModifyReference g (swap . randomR (0,0xffffffffffffffff))
where swap (a,b) = (b,fromInteger a)
getRandomDoubleFromRandomGenRef :: (Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> m Double
getRandomDoubleFromRandomGenRef g = liftM wordToDouble (getRandomWordFromRandomGenRef g)
getRandomByteFromRandomGenState :: (RandomGen g, MonadState g m) => m Word8
getRandomByteFromRandomGenState = do
g <- get
case randomR (0, 255 :: Int) g of
(i,g) -> do
put g
return (fromIntegral i)
getRandomWordFromRandomGenState :: (RandomGen g, MonadState g m) => m Word64
getRandomWordFromRandomGenState = do
g <- get
case randomR (0, 0xffffffffffffffff) g of
(i,g) -> do
put g
return (fromInteger i)
getRandomDoubleFromRandomGenState :: (RandomGen g, MonadState g m) => m Double
getRandomDoubleFromRandomGenState = liftM wordToDouble getRandomWordFromRandomGenState
instance MonadRandom (State StdGen) where
getRandomByte = getRandomByteFromRandomGenState
getRandomWord = getRandomWordFromRandomGenState
getRandomDouble = getRandomDoubleFromRandomGenState
instance Monad m => MonadRandom (StateT StdGen m) where
getRandomByte = getRandomByteFromRandomGenState
getRandomWord = getRandomWordFromRandomGenState
getRandomDouble = getRandomDoubleFromRandomGenState
instance MonadRandom (S.State StdGen) where
getRandomByte = getRandomByteFromRandomGenState
getRandomWord = getRandomWordFromRandomGenState
getRandomDouble = getRandomDoubleFromRandomGenState
instance Monad m => MonadRandom (S.StateT StdGen m) where
getRandomByte = getRandomByteFromRandomGenState
getRandomWord = getRandomWordFromRandomGenState
getRandomDouble = getRandomDoubleFromRandomGenState