{-# LANGUAGE
CPP,
MultiParamTypeClasses, FlexibleInstances, UndecidableInstances, GADTs,
BangPatterns, RankNTypes,
ScopedTypeVariables
#-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Random.Source.StdGen
( StdGen
, mkStdGen
, newStdGen
, getRandomPrimFromStdGenIO
, getRandomPrimFromRandomGenRef
, getRandomPrimFromRandomGenState
) where
import Data.Random.Internal.Source
import System.Random
import Control.Monad.State
import Control.Monad.RWS
import qualified Control.Monad.ST.Strict as S
import qualified Control.Monad.State.Strict as S
import qualified Control.Monad.RWS.Strict as S
import Data.StateRef
import Data.Word
instance (Monad m1, ModifyRef (Ref m2 StdGen) m1 StdGen) => RandomSource m1 (Ref m2 StdGen) where
getRandomPrimFrom :: Ref m2 StdGen -> Prim t -> m1 t
getRandomPrimFrom = Ref m2 StdGen -> Prim t -> m1 t
forall (m :: * -> *) sr g a.
(Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> Prim a -> m a
getRandomPrimFromRandomGenRef
instance (Monad m, ModifyRef (IORef StdGen) m StdGen) => RandomSource m (IORef StdGen) where
{-# SPECIALIZE instance RandomSource IO (IORef StdGen) #-}
getRandomPrimFrom :: IORef StdGen -> Prim t -> m t
getRandomPrimFrom = IORef StdGen -> Prim t -> m t
forall (m :: * -> *) sr g a.
(Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> Prim a -> m a
getRandomPrimFromRandomGenRef
instance (Monad m, ModifyRef (STRef s StdGen) m StdGen) => RandomSource m (STRef s StdGen) where
{-# SPECIALIZE instance RandomSource (ST s) (STRef s StdGen) #-}
{-# SPECIALIZE instance RandomSource (S.ST s) (STRef s StdGen) #-}
getRandomPrimFrom :: STRef s StdGen -> Prim t -> m t
getRandomPrimFrom = STRef s StdGen -> Prim t -> m t
forall (m :: * -> *) sr g a.
(Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> Prim a -> m a
getRandomPrimFromRandomGenRef
getRandomPrimFromStdGenIO :: Prim a -> IO a
getRandomPrimFromStdGenIO :: Prim a -> IO a
getRandomPrimFromStdGenIO
= (StdGen -> (a, StdGen)) -> IO a
forall a. (StdGen -> (a, StdGen)) -> IO a
getStdRandom
((StdGen -> (a, StdGen)) -> IO a)
-> (Prim a -> StdGen -> (a, StdGen)) -> Prim a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. State StdGen a -> StdGen -> (a, StdGen)
forall s a. State s a -> s -> (a, s)
runState
(State StdGen a -> StdGen -> (a, StdGen))
-> (Prim a -> State StdGen a) -> Prim a -> StdGen -> (a, StdGen)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Prim a -> State StdGen a
forall (m :: * -> *) t. MonadRandom m => Prim t -> m t
getRandomPrim
getRandomPrimFromRandomGenRef :: (Monad m, ModifyRef sr m g, RandomGen g) =>
sr -> Prim a -> m a
getRandomPrimFromRandomGenRef :: sr -> Prim a -> m a
getRandomPrimFromRandomGenRef ref :: sr
ref
= sr -> (g -> (a, g)) -> m a
forall sr (m :: * -> *) a b.
ModifyRef sr m a =>
sr -> (a -> (b, a)) -> m b
atomicModifyReference' sr
ref
((g -> (a, g)) -> m a) -> (Prim a -> g -> (a, g)) -> Prim a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. State g a -> g -> (a, g)
forall s a. State s a -> s -> (a, s)
runState
(State g a -> g -> (a, g))
-> (Prim a -> State g a) -> Prim a -> g -> (a, g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Prim a -> State g a
forall g (m :: * -> *) a.
(RandomGen g, MonadState g m) =>
Prim a -> m a
getRandomPrimFromRandomGenState
atomicModifyReference' :: ModifyRef sr m a => sr -> (a -> (b, a)) -> m b
atomicModifyReference' :: sr -> (a -> (b, a)) -> m b
atomicModifyReference' ref :: sr
ref getR :: a -> (b, a)
getR =
sr -> (a -> (a, b)) -> m b
forall sr (m :: * -> *) a b.
ModifyRef sr m a =>
sr -> (a -> (a, b)) -> m b
atomicModifyReference sr
ref ((b, a) -> (a, b)
forall b a. (b, a) -> (a, b)
swap' ((b, a) -> (a, b)) -> (a -> (b, a)) -> a -> (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, a)
getR)
where swap' :: (b, a) -> (a, b)
swap' (!b
a,!a
b) = (a
b,b
a)
{-# SPECIALIZE getRandomPrimFromRandomGenState :: Prim a -> State StdGen a #-}
{-# SPECIALIZE getRandomPrimFromRandomGenState :: Monad m => Prim a -> StateT StdGen m a #-}
getRandomPrimFromRandomGenState :: forall g m a. (RandomGen g, MonadState g m) => Prim a -> m a
getRandomPrimFromRandomGenState :: Prim a -> m a
getRandomPrimFromRandomGenState = Prim a -> m a
forall t. Prim t -> m t
genPrim
where
{-# INLINE genPrim #-}
genPrim :: forall t. Prim t -> m t
genPrim :: Prim t -> m t
genPrim PrimWord8 = (g -> (Int, g)) -> (Int -> Word8) -> m Word8
forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing ((Int, Int) -> g -> (Int, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, 0xff)) (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Int -> Word8)
genPrim PrimWord16 = (g -> (Int, g)) -> (Int -> Word16) -> m Word16
forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing ((Int, Int) -> g -> (Int, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, 0xffff)) (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Int -> Word16)
genPrim PrimWord32 = (g -> (Integer, g)) -> (Integer -> t) -> m t
forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing ((Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, 0xffffffff)) (Integer -> t
forall a. Num a => Integer -> a
fromInteger)
genPrim PrimWord64 = (g -> (Integer, g)) -> (Integer -> t) -> m t
forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing ((Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, 0xffffffffffffffff)) (Integer -> t
forall a. Num a => Integer -> a
fromInteger)
genPrim PrimDouble = (g -> (Integer, g)) -> (Integer -> t) -> m t
forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing ((Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, 0x000fffffffffffff)) ((Integer -> Int -> t) -> Int -> Integer -> t
forall a b c. (a -> b -> c) -> b -> a -> c
flip Integer -> Int -> t
forall a. RealFloat a => Integer -> Int -> a
encodeFloat (-52))
genPrim (PrimNByteInteger n :: Int
n) = (g -> (t, g)) -> (t -> t) -> m t
forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing ((t, t) -> g -> (t, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, (t -> t) -> t -> [t]
forall a. (a -> a) -> a -> [a]
iterate (t -> t -> t
forall a. Num a => a -> a -> a
*256) 1 [t] -> Int -> t
forall a. [a] -> Int -> a
!! Int
n)) t -> t
forall a. a -> a
id
{-# INLINE getThing #-}
getThing :: forall b t. (g -> (b, g)) -> (b -> t) -> m t
getThing :: (g -> (b, g)) -> (b -> t) -> m t
getThing thing :: g -> (b, g)
thing f :: b -> t
f = do
!g
oldGen <- m g
forall s (m :: * -> *). MonadState s m => m s
get
case g -> (b, g)
thing g
oldGen of
(!b
i,!g
newGen) -> do
g -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put g
newGen
t -> m t
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> t
f (b -> t) -> b -> t
forall a b. (a -> b) -> a -> b
$! b
i)
#ifndef MTL2
instance MonadRandom (State StdGen) where
getRandomPrim = getRandomPrimFromRandomGenState
instance MonadRandom (S.State StdGen) where
getRandomPrim = getRandomPrimFromRandomGenState
instance Monoid w => MonadRandom (RWS r w StdGen) where
getRandomPrim = getRandomPrimFromRandomGenState
instance Monoid w => MonadRandom (S.RWS r w StdGen) where
getRandomPrim = getRandomPrimFromRandomGenState
#endif
instance Monad m => MonadRandom (StateT StdGen m) where
getRandomPrim :: Prim t -> StateT StdGen m t
getRandomPrim = Prim t -> StateT StdGen m t
forall g (m :: * -> *) a.
(RandomGen g, MonadState g m) =>
Prim a -> m a
getRandomPrimFromRandomGenState
instance Monad m => MonadRandom (S.StateT StdGen m) where
getRandomPrim :: Prim t -> StateT StdGen m t
getRandomPrim = Prim t -> StateT StdGen m t
forall g (m :: * -> *) a.
(RandomGen g, MonadState g m) =>
Prim a -> m a
getRandomPrimFromRandomGenState
instance (Monad m, Monoid w) => MonadRandom (RWST r w StdGen m) where
getRandomPrim :: Prim t -> RWST r w StdGen m t
getRandomPrim = Prim t -> RWST r w StdGen m t
forall g (m :: * -> *) a.
(RandomGen g, MonadState g m) =>
Prim a -> m a
getRandomPrimFromRandomGenState
instance (Monad m, Monoid w) => MonadRandom (S.RWST r w StdGen m) where
getRandomPrim :: Prim t -> RWST r w StdGen m t
getRandomPrim = Prim t -> RWST r w StdGen m t
forall g (m :: * -> *) a.
(RandomGen g, MonadState g m) =>
Prim a -> m a
getRandomPrimFromRandomGenState