{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
#if __GLASGOW_HASKELL__ >= 801
{-# LANGUAGE TypeInType #-}
#endif
{-# LANGUAGE UnboxedTuples #-}
#if __GLASGOW_HASKELL__ >= 707
{-# LANGUAGE RoleAnnotations #-}
#endif
module System.Random.PCG.Fast.Pure
(
Gen, GenIO, GenST
, create, createSystemRandom, initialize, withSystemRandom
, Variate (..)
, advance, retract
, FrozenGen, save, restore, seed, initFrozen
, uniformW8, uniformW16, uniformW32, uniformW64
, uniformI8, uniformI16, uniformI32, uniformI64
, uniformF, uniformD, uniformBool
, uniformRW8, uniformRW16, uniformRW32, uniformRW64
, uniformRI8, uniformRI16, uniformRI32, uniformRI64
, uniformRF, uniformRD, uniformRBool
, uniformBW8, uniformBW16, uniformBW32, uniformBW64
, uniformBI8, uniformBI16, uniformBI32, uniformBI64
, uniformBF, uniformBD, uniformBBool
) where
import Control.Monad.Primitive
import Data.Bits
import Data.Data
import Data.Primitive.ByteArray
import Data.Primitive.Types
import GHC.Generics
import GHC.Word
import System.Random
import System.Random.PCG.Class
newtype FrozenGen = F Word64
deriving (Int -> FrozenGen -> ShowS
[FrozenGen] -> ShowS
FrozenGen -> String
(Int -> FrozenGen -> ShowS)
-> (FrozenGen -> String)
-> ([FrozenGen] -> ShowS)
-> Show FrozenGen
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FrozenGen] -> ShowS
$cshowList :: [FrozenGen] -> ShowS
show :: FrozenGen -> String
$cshow :: FrozenGen -> String
showsPrec :: Int -> FrozenGen -> ShowS
$cshowsPrec :: Int -> FrozenGen -> ShowS
Show, FrozenGen -> FrozenGen -> Bool
(FrozenGen -> FrozenGen -> Bool)
-> (FrozenGen -> FrozenGen -> Bool) -> Eq FrozenGen
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FrozenGen -> FrozenGen -> Bool
$c/= :: FrozenGen -> FrozenGen -> Bool
== :: FrozenGen -> FrozenGen -> Bool
$c== :: FrozenGen -> FrozenGen -> Bool
Eq, Eq FrozenGen
Eq FrozenGen
-> (FrozenGen -> FrozenGen -> Ordering)
-> (FrozenGen -> FrozenGen -> Bool)
-> (FrozenGen -> FrozenGen -> Bool)
-> (FrozenGen -> FrozenGen -> Bool)
-> (FrozenGen -> FrozenGen -> Bool)
-> (FrozenGen -> FrozenGen -> FrozenGen)
-> (FrozenGen -> FrozenGen -> FrozenGen)
-> Ord FrozenGen
FrozenGen -> FrozenGen -> Bool
FrozenGen -> FrozenGen -> Ordering
FrozenGen -> FrozenGen -> FrozenGen
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: FrozenGen -> FrozenGen -> FrozenGen
$cmin :: FrozenGen -> FrozenGen -> FrozenGen
max :: FrozenGen -> FrozenGen -> FrozenGen
$cmax :: FrozenGen -> FrozenGen -> FrozenGen
>= :: FrozenGen -> FrozenGen -> Bool
$c>= :: FrozenGen -> FrozenGen -> Bool
> :: FrozenGen -> FrozenGen -> Bool
$c> :: FrozenGen -> FrozenGen -> Bool
<= :: FrozenGen -> FrozenGen -> Bool
$c<= :: FrozenGen -> FrozenGen -> Bool
< :: FrozenGen -> FrozenGen -> Bool
$c< :: FrozenGen -> FrozenGen -> Bool
compare :: FrozenGen -> FrozenGen -> Ordering
$ccompare :: FrozenGen -> FrozenGen -> Ordering
Ord, Addr# -> Int# -> FrozenGen
ByteArray# -> Int# -> FrozenGen
FrozenGen -> Int#
(FrozenGen -> Int#)
-> (FrozenGen -> Int#)
-> (ByteArray# -> Int# -> FrozenGen)
-> (forall s.
MutableByteArray# s
-> Int# -> State# s -> (# State# s, FrozenGen #))
-> (forall s.
MutableByteArray# s -> Int# -> FrozenGen -> State# s -> State# s)
-> (forall s.
MutableByteArray# s
-> Int# -> Int# -> FrozenGen -> State# s -> State# s)
-> (Addr# -> Int# -> FrozenGen)
-> (forall s.
Addr# -> Int# -> State# s -> (# State# s, FrozenGen #))
-> (forall s. Addr# -> Int# -> FrozenGen -> State# s -> State# s)
-> (forall s.
Addr# -> Int# -> Int# -> FrozenGen -> State# s -> State# s)
-> Prim FrozenGen
forall s.
Addr# -> Int# -> Int# -> FrozenGen -> State# s -> State# s
forall s. Addr# -> Int# -> State# s -> (# State# s, FrozenGen #)
forall s. Addr# -> Int# -> FrozenGen -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> Int# -> FrozenGen -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> State# s -> (# State# s, FrozenGen #)
forall s.
MutableByteArray# s -> Int# -> FrozenGen -> State# s -> State# s
forall a.
(a -> Int#)
-> (a -> Int#)
-> (ByteArray# -> Int# -> a)
-> (forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #))
-> (forall s.
MutableByteArray# s -> Int# -> a -> State# s -> State# s)
-> (forall s.
MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s)
-> (Addr# -> Int# -> a)
-> (forall s. Addr# -> Int# -> State# s -> (# State# s, a #))
-> (forall s. Addr# -> Int# -> a -> State# s -> State# s)
-> (forall s. Addr# -> Int# -> Int# -> a -> State# s -> State# s)
-> Prim a
setOffAddr# :: forall s.
Addr# -> Int# -> Int# -> FrozenGen -> State# s -> State# s
$csetOffAddr# :: forall s.
Addr# -> Int# -> Int# -> FrozenGen -> State# s -> State# s
writeOffAddr# :: forall s. Addr# -> Int# -> FrozenGen -> State# s -> State# s
$cwriteOffAddr# :: forall s. Addr# -> Int# -> FrozenGen -> State# s -> State# s
readOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, FrozenGen #)
$creadOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, FrozenGen #)
indexOffAddr# :: Addr# -> Int# -> FrozenGen
$cindexOffAddr# :: Addr# -> Int# -> FrozenGen
setByteArray# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> FrozenGen -> State# s -> State# s
$csetByteArray# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> FrozenGen -> State# s -> State# s
writeByteArray# :: forall s.
MutableByteArray# s -> Int# -> FrozenGen -> State# s -> State# s
$cwriteByteArray# :: forall s.
MutableByteArray# s -> Int# -> FrozenGen -> State# s -> State# s
readByteArray# :: forall s.
MutableByteArray# s
-> Int# -> State# s -> (# State# s, FrozenGen #)
$creadByteArray# :: forall s.
MutableByteArray# s
-> Int# -> State# s -> (# State# s, FrozenGen #)
indexByteArray# :: ByteArray# -> Int# -> FrozenGen
$cindexByteArray# :: ByteArray# -> Int# -> FrozenGen
alignment# :: FrozenGen -> Int#
$calignment# :: FrozenGen -> Int#
sizeOf# :: FrozenGen -> Int#
$csizeOf# :: FrozenGen -> Int#
Prim, Typeable, Typeable FrozenGen
Typeable FrozenGen
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FrozenGen -> c FrozenGen)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FrozenGen)
-> (FrozenGen -> Constr)
-> (FrozenGen -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FrozenGen))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FrozenGen))
-> ((forall b. Data b => b -> b) -> FrozenGen -> FrozenGen)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r)
-> (forall u. (forall d. Data d => d -> u) -> FrozenGen -> [u])
-> (forall u.
Int -> (forall d. Data d => d -> u) -> FrozenGen -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen)
-> Data FrozenGen
FrozenGen -> DataType
FrozenGen -> Constr
(forall b. Data b => b -> b) -> FrozenGen -> FrozenGen
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> FrozenGen -> u
forall u. (forall d. Data d => d -> u) -> FrozenGen -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FrozenGen
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FrozenGen -> c FrozenGen
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FrozenGen)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FrozenGen)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FrozenGen -> m FrozenGen
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FrozenGen -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FrozenGen -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> FrozenGen -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> FrozenGen -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FrozenGen -> r
gmapT :: (forall b. Data b => b -> b) -> FrozenGen -> FrozenGen
$cgmapT :: (forall b. Data b => b -> b) -> FrozenGen -> FrozenGen
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FrozenGen)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FrozenGen)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FrozenGen)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FrozenGen)
dataTypeOf :: FrozenGen -> DataType
$cdataTypeOf :: FrozenGen -> DataType
toConstr :: FrozenGen -> Constr
$ctoConstr :: FrozenGen -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FrozenGen
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FrozenGen
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FrozenGen -> c FrozenGen
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FrozenGen -> c FrozenGen
Data, (forall x. FrozenGen -> Rep FrozenGen x)
-> (forall x. Rep FrozenGen x -> FrozenGen) -> Generic FrozenGen
forall x. Rep FrozenGen x -> FrozenGen
forall x. FrozenGen -> Rep FrozenGen x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FrozenGen x -> FrozenGen
$cfrom :: forall x. FrozenGen -> Rep FrozenGen x
Generic)
newtype Gen s = G (MutableByteArray s)
deriving Typeable
type GenIO = Gen RealWorld
type GenST = Gen
data Pair = P {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word32
deriving Int -> Pair -> ShowS
[Pair] -> ShowS
Pair -> String
(Int -> Pair -> ShowS)
-> (Pair -> String) -> ([Pair] -> ShowS) -> Show Pair
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pair] -> ShowS
$cshowList :: [Pair] -> ShowS
show :: Pair -> String
$cshow :: Pair -> String
showsPrec :: Int -> Pair -> ShowS
$cshowsPrec :: Int -> Pair -> ShowS
Show
fastMultiplier :: Word64
fastMultiplier :: Word64
fastMultiplier = Word64
6364136223846793005
state :: Word64 -> Word64
state :: Word64 -> Word64
state Word64
s = Word64
s Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
fastMultiplier
output :: Word64 -> Word32
output :: Word64 -> Word32
output Word64
s = Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word32) -> Word64 -> Word32
forall a b. (a -> b) -> a -> b
$
((Word64
s Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
22) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64
s) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
s Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
61) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
22)
pair :: Word64 -> Pair
pair :: Word64 -> Pair
pair Word64
s = Word64 -> Word32 -> Pair
P (Word64 -> Word64
state Word64
s) (Word64 -> Word32
output Word64
s)
bounded :: Word32 -> Word64 -> Pair
bounded :: Word32 -> Word64 -> Pair
bounded Word32
b Word64
s0 = Word64 -> Pair
go Word64
s0
where
t :: Word32
t = Word32 -> Word32
forall a. Num a => a -> a
negate Word32
b Word32 -> Word32 -> Word32
forall a. Integral a => a -> a -> a
`mod` Word32
b
go :: Word64 -> Pair
go !Word64
s | Word32
r Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
t = Word64 -> Word32 -> Pair
P Word64
s' (Word32
r Word32 -> Word32 -> Word32
forall a. Integral a => a -> a -> a
`mod` Word32
b)
| Bool
otherwise = Word64 -> Pair
go Word64
s'
where P Word64
s' Word32
r = Word64 -> Pair
pair Word64
s
{-# INLINE bounded #-}
advancing
:: Word64
-> Word64
-> Word64
-> Word64
-> Word64
advancing :: Word64 -> Word64 -> Word64 -> Word64 -> Word64
advancing Word64
d0 Word64
s Word64
m0 Word64
p0 = Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
go Word64
d0 Word64
m0 Word64
p0 Word64
1 Word64
0
where
go :: Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
go Word64
d Word64
cm Word64
cp Word64
am Word64
ap
| Word64
d Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
0 = Word64
am Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
s Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
ap
| Word64 -> Bool
forall a. Integral a => a -> Bool
odd Word64
d = Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
go Word64
d' Word64
cm' Word64
cp' (Word64
am Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
cm) (Word64
ap Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
cm Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
cp)
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
go Word64
d' Word64
cm' Word64
cp' Word64
am Word64
ap
where
cm' :: Word64
cm' = Word64
cm Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
cm
cp' :: Word64
cp' = (Word64
cm Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
cp
d' :: Word64
d' = Word64
d Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` Word64
2
advanceFast :: Word64 -> FrozenGen -> FrozenGen
advanceFast :: Word64 -> FrozenGen -> FrozenGen
advanceFast Word64
d (F Word64
s) = Word64 -> FrozenGen
F (Word64 -> FrozenGen) -> Word64 -> FrozenGen
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Word64 -> Word64 -> Word64
advancing Word64
d Word64
s Word64
fastMultiplier Word64
0
save :: PrimMonad m => Gen (PrimState m) -> m FrozenGen
save :: forall (m :: * -> *).
PrimMonad m =>
Gen (PrimState m) -> m FrozenGen
save (G MutableByteArray (PrimState m)
a) = MutableByteArray (PrimState m) -> Int -> m FrozenGen
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray (PrimState m)
a Int
0
{-# INLINE save #-}
restore :: PrimMonad m => FrozenGen -> m (Gen (PrimState m))
restore :: forall (m :: * -> *).
PrimMonad m =>
FrozenGen -> m (Gen (PrimState m))
restore FrozenGen
f = do
MutableByteArray (PrimState m)
a <- Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
8
MutableByteArray (PrimState m) -> Int -> FrozenGen -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray (PrimState m)
a Int
0 FrozenGen
f
Gen (PrimState m) -> m (Gen (PrimState m))
forall (m :: * -> *) a. Monad m => a -> m a
return (Gen (PrimState m) -> m (Gen (PrimState m)))
-> Gen (PrimState m) -> m (Gen (PrimState m))
forall a b. (a -> b) -> a -> b
$! MutableByteArray (PrimState m) -> Gen (PrimState m)
forall s. MutableByteArray s -> Gen s
G MutableByteArray (PrimState m)
a
{-# INLINE restore #-}
initFrozen :: Word64 -> FrozenGen
initFrozen :: Word64 -> FrozenGen
initFrozen Word64
w = Word64 -> FrozenGen
F (Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
1)
seed :: FrozenGen
seed :: FrozenGen
seed = Word64 -> FrozenGen
F Word64
0xcafef00dd15ea5e5
create :: PrimMonad m => m (Gen (PrimState m))
create :: forall (m :: * -> *). PrimMonad m => m (Gen (PrimState m))
create = FrozenGen -> m (Gen (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
FrozenGen -> m (Gen (PrimState m))
restore FrozenGen
seed
initialize :: PrimMonad m => Word64 -> m (Gen (PrimState m))
initialize :: forall (m :: * -> *).
PrimMonad m =>
Word64 -> m (Gen (PrimState m))
initialize Word64
a = FrozenGen -> m (Gen (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
FrozenGen -> m (Gen (PrimState m))
restore (Word64 -> FrozenGen
initFrozen Word64
a)
withSystemRandom :: (GenIO -> IO a) -> IO a
withSystemRandom :: forall a. (GenIO -> IO a) -> IO a
withSystemRandom GenIO -> IO a
f = do
Word64
w <- IO Word64
sysRandom
Word64 -> IO (Gen (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Word64 -> m (Gen (PrimState m))
initialize Word64
w IO GenIO -> (GenIO -> IO a) -> IO a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= GenIO -> IO a
f
createSystemRandom :: IO GenIO
createSystemRandom :: IO GenIO
createSystemRandom = (GenIO -> IO GenIO) -> IO GenIO
forall a. (GenIO -> IO a) -> IO a
withSystemRandom (GenIO -> IO GenIO
forall (m :: * -> *) a. Monad m => a -> m a
return :: GenIO -> IO GenIO)
advance :: PrimMonad m => Word64 -> Gen (PrimState m) -> m ()
advance :: forall (m :: * -> *).
PrimMonad m =>
Word64 -> Gen (PrimState m) -> m ()
advance Word64
u (G MutableByteArray (PrimState m)
a) = do
FrozenGen
s <- MutableByteArray (PrimState m) -> Int -> m FrozenGen
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray (PrimState m)
a Int
0
let s' :: FrozenGen
s' = Word64 -> FrozenGen -> FrozenGen
advanceFast Word64
u FrozenGen
s
MutableByteArray (PrimState m) -> Int -> FrozenGen -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray (PrimState m)
a Int
0 FrozenGen
s'
{-# INLINE advance #-}
retract :: PrimMonad m => Word64 -> Gen (PrimState m) -> m ()
retract :: forall (m :: * -> *).
PrimMonad m =>
Word64 -> Gen (PrimState m) -> m ()
retract Word64
u Gen (PrimState m)
g = Word64 -> Gen (PrimState m) -> m ()
forall (m :: * -> *).
PrimMonad m =>
Word64 -> Gen (PrimState m) -> m ()
advance (-Word64
u) Gen (PrimState m)
g
{-# INLINE retract #-}
instance (PrimMonad m, s ~ PrimState m) => Generator (Gen s) m where
uniform1 :: forall a. (Word32 -> a) -> Gen s -> m a
uniform1 Word32 -> a
f (G MutableByteArray s
a) = do
Word64
s <- MutableByteArray (PrimState m) -> Int -> m Word64
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray s
MutableByteArray (PrimState m)
a Int
0
let P Word64
s' Word32
r = Word64 -> Pair
pair Word64
s
MutableByteArray (PrimState m) -> Int -> Word64 -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState m)
a Int
0 Word64
s'
a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$! Word32 -> a
f Word32
r
{-# INLINE uniform1 #-}
uniform2 :: forall a. (Word32 -> Word32 -> a) -> Gen s -> m a
uniform2 Word32 -> Word32 -> a
f (G MutableByteArray s
a) = do
Word64
s <- MutableByteArray (PrimState m) -> Int -> m Word64
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray s
MutableByteArray (PrimState m)
a Int
0
let s' :: Word64
s' = Word64 -> Word64
state Word64
s
MutableByteArray (PrimState m) -> Int -> Word64 -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState m)
a Int
0 (Word64 -> Word64
state Word64
s')
a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$! Word32 -> Word32 -> a
f (Word64 -> Word32
output Word64
s) (Word64 -> Word32
output Word64
s')
{-# INLINE uniform2 #-}
uniform1B :: forall a. Integral a => (Word32 -> a) -> Word32 -> Gen s -> m a
uniform1B Word32 -> a
f Word32
b (G MutableByteArray s
a) = do
Word64
s <- MutableByteArray (PrimState m) -> Int -> m Word64
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray s
MutableByteArray (PrimState m)
a Int
0
let P Word64
s' Word32
r = Word32 -> Word64 -> Pair
bounded Word32
b Word64
s
MutableByteArray (PrimState m) -> Int -> Word64 -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState m)
a Int
0 Word64
s'
a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$! Word32 -> a
f Word32
r
{-# INLINE uniform1B #-}
instance RandomGen FrozenGen where
genWord32 :: FrozenGen -> (Word32, FrozenGen)
genWord32 (F Word64
s) = (Word32
w, Word64 -> FrozenGen
F Word64
s')
where
P Word64
s' Word32
w = Word64 -> Pair
pair Word64
s
{-# INLINE genWord32 #-}
genWord64 :: FrozenGen -> (Word64, FrozenGen)
genWord64 (F Word64
s) = (Word32 -> Word32 -> Word64
forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit Word32
w1 Word32
w2, Word64 -> FrozenGen
F Word64
s'')
where
P Word64
s' Word32
w1 = Word64 -> Pair
pair Word64
s
P Word64
s'' Word32
w2 = Word64 -> Pair
pair Word64
s'
{-# INLINE genWord64 #-}
split :: FrozenGen -> (FrozenGen, FrozenGen)
split (F Word64
s) = (Word32 -> Word32 -> FrozenGen
mk Word32
w1 Word32
w2, Word32 -> Word32 -> FrozenGen
mk Word32
w3 Word32
w4)
where
mk :: Word32 -> Word32 -> FrozenGen
mk Word32
a Word32
b = Word64 -> FrozenGen
initFrozen (Word64 -> FrozenGen) -> Word64 -> FrozenGen
forall a b. (a -> b) -> a -> b
$! Word32 -> Word32 -> Word64
forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit Word32
a Word32
b
P Word64
s1 Word32
w1 = Word64 -> Pair
pair Word64
s
P Word64
s2 Word32
w2 = Word64 -> Pair
pair Word64
s1
P Word64
s3 Word32
w3 = Word64 -> Pair
pair Word64
s2
w4 :: Word32
w4 = Word64 -> Word32
output Word64
s3
{-# INLINE split #-}