{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
module System.Random.PCG.Class
(
Generator (..)
, Variate (..)
, 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
, Unsigned
, wordsTo64Bit
, wordToBool
, wordToFloat
, wordsToDouble
, sysRandom
) where
#if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
#include "MachDeps.h"
#endif
import qualified Data.Kind
import Control.Monad
import Data.Bits
import Data.ByteString (useAsCString)
import Data.Int
import Data.Word
import Foreign (castPtr, peek)
import System.Entropy
class Monad m => Generator g m where
uniform1 :: (Word32 -> a) -> g -> m a
uniform2 :: (Word32 -> Word32 -> a) -> g -> m a
uniform1B :: Integral a => (Word32 -> a) -> Word32 -> g -> m a
class Variate a where
uniform :: Generator g m => g -> m a
uniformR :: Generator g m => (a,a) -> g -> m a
uniformB :: Generator g m => a -> g -> m a
instance Variate Int8 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Int8
uniform = (Word32 -> Int8) -> g -> m Int8
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Int8, Int8) -> g -> m Int8
uniformR (Int8, Int8)
a g
g = (Int8, Int8) -> g -> m Int8
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Int8, Int8)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Int8 -> g -> m Int8
uniformB Int8
b g
g = (Word32 -> Int8) -> Word32 -> g -> m Int8
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int8
b) g
g
{-# INLINE uniformB #-}
instance Variate Int16 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Int16
uniform = (Word32 -> Int16) -> g -> m Int16
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Int16, Int16) -> g -> m Int16
uniformR (Int16, Int16)
a g
g = (Int16, Int16) -> g -> m Int16
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Int16, Int16)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Int16 -> g -> m Int16
uniformB Int16
b g
g = (Word32 -> Int16) -> Word32 -> g -> m Int16
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
b) g
g
{-# INLINE uniformB #-}
instance Variate Int32 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Int32
uniform = (Word32 -> Int32) -> g -> m Int32
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Int32, Int32) -> g -> m Int32
uniformR (Int32, Int32)
a g
g = (Int32, Int32) -> g -> m Int32
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Int32, Int32)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Int32 -> g -> m Int32
uniformB Int32
b g
g = (Word32 -> Int32) -> Word32 -> g -> m Int32
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
b) g
g
{-# INLINE uniformB #-}
instance Variate Int64 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Int64
uniform = (Word32 -> Word32 -> Int64) -> g -> m Int64
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> Word32 -> a) -> g -> m a
uniform2 Word32 -> Word32 -> Int64
forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Int64, Int64) -> g -> m Int64
uniformR (Int64, Int64)
a g
g = (Int64, Int64) -> g -> m Int64
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Int64, Int64)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Int64 -> g -> m Int64
uniformB Int64
b g
g = (Word32 -> Int64) -> Word32 -> g -> m Int64
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
b) g
g
{-# INLINE uniformB #-}
instance Variate Word8 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Word8
uniform = (Word32 -> Word8) -> g -> m Word8
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Word8, Word8) -> g -> m Word8
uniformR (Word8, Word8)
a g
g = (Word8, Word8) -> g -> m Word8
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Word8, Word8)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Word8 -> g -> m Word8
uniformB Word8
b g
g = (Word32 -> Word8) -> Word32 -> g -> m Word8
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b) g
g
{-# INLINE uniformB #-}
instance Variate Word16 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Word16
uniform = (Word32 -> Word16) -> g -> m Word16
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Word16, Word16) -> g -> m Word16
uniformR (Word16, Word16)
a g
g = (Word16, Word16) -> g -> m Word16
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Word16, Word16)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Word16 -> g -> m Word16
uniformB Word16
b g
g = (Word32 -> Word16) -> Word32 -> g -> m Word16
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
b) g
g
{-# INLINE uniformB #-}
instance Variate Word32 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Word32
uniform = (Word32 -> Word32) -> g -> m Word32
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Word32, Word32) -> g -> m Word32
uniformR (Word32, Word32)
a g
g = (Word32, Word32) -> g -> m Word32
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Word32, Word32)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Word32 -> g -> m Word32
uniformB Word32
b g
g = (Word32 -> Word32) -> Word32 -> g -> m Word32
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
b) g
g
{-# INLINE uniformB #-}
instance Variate Word64 where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Word64
uniform = (Word32 -> Word32 -> Word64) -> g -> m Word64
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> Word32 -> a) -> g -> m a
uniform2 Word32 -> Word32 -> Word64
forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Word64, Word64) -> g -> m Word64
uniformR (Word64, Word64)
a g
g = (Word64, Word64) -> g -> m Word64
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Word64, Word64)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Word64 -> g -> m Word64
uniformB Word64
b g
g = (Word32 -> Word64) -> Word32 -> g -> m Word64
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
b) g
g
{-# INLINE uniformB #-}
instance Variate Bool where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Bool
uniform = (Word32 -> Bool) -> g -> m Bool
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Bool
wordToBool
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Bool, Bool) -> g -> m Bool
uniformR (Bool
False,Bool
True) g
g = g -> m Bool
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
uniformR (Bool
False,Bool
False) g
_ = Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
uniformR (Bool
True,Bool
True) g
_ = Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
uniformR (Bool
True,Bool
False) g
g = g -> m Bool
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Bool -> g -> m Bool
uniformB Bool
False g
_ = Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
uniformB Bool
_ g
g = g -> m Bool
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
{-# INLINE uniformB #-}
instance Variate Float where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Float
uniform = (Word32 -> Float) -> g -> m Float
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 Word32 -> Float
wordToFloat
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Float, Float) -> g -> m Float
uniformR (Float
x1,Float
x2) = (Word32 -> Float) -> g -> m Float
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> a) -> g -> m a
uniform1 (\Word32
w -> Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
x2Float -> Float -> Float
forall a. Num a => a -> a -> a
-Float
x1) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Word32 -> Float
wordToFloat Word32
w)
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Float -> g -> m Float
uniformB Float
b g
g = (Float -> Float -> Float
forall a. Num a => a -> a -> a
subtract Float
1.16415321826934814453125e-10) (Float -> Float) -> m Float -> m Float
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` (Float, Float) -> g -> m Float
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (Float
0,Float
b) g
g
{-# INLINE uniformB #-}
instance Variate Double where
uniform :: forall g (m :: * -> *). Generator g m => g -> m Double
uniform = (Word32 -> Word32 -> Double) -> g -> m Double
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> Word32 -> a) -> g -> m a
uniform2 Word32 -> Word32 -> Double
wordsToDouble
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Double, Double) -> g -> m Double
uniformR (Double
x1,Double
x2) = (Word32 -> Word32 -> Double) -> g -> m Double
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> Word32 -> a) -> g -> m a
uniform2 (\Word32
w1 Word32
w2 -> Double
x1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (Double
x2Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
x1) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Word32 -> Word32 -> Double
wordsToDouble Word32
w1 Word32
w2)
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Double -> g -> m Double
uniformB Double
b g
g = (Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract Double
1.1102230246251565404236316680908203125e-16) (Double -> Double) -> m Double -> m Double
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` (Double, Double) -> g -> m Double
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (Double
0,Double
b) g
g
{-# INLINE uniformB #-}
instance Variate Word where
#if WORD_SIZE_IN_BITS < 64
uniform = uniform1 fromIntegral
#else
uniform :: forall g (m :: * -> *). Generator g m => g -> m Word
uniform = (Word32 -> Word32 -> Word) -> g -> m Word
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> Word32 -> a) -> g -> m a
uniform2 Word32 -> Word32 -> Word
forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit
#endif
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
(Word, Word) -> g -> m Word
uniformR (Word, Word)
a g
g = (Word, Word) -> g -> m Word
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Word, Word)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Word -> g -> m Word
uniformB Word
b g
g = (Word32 -> Word) -> Word32 -> g -> m Word
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
b) g
g
{-# INLINE uniformB #-}
instance Variate Int where
#if WORD_SIZE_IN_BITS < 64
uniform = uniform1 fromIntegral
#else
uniform :: forall g (m :: * -> *). Generator g m => g -> m Int
uniform = (Word32 -> Word32 -> Int) -> g -> m Int
forall g (m :: * -> *) a.
Generator g m =>
(Word32 -> Word32 -> a) -> g -> m a
uniform2 Word32 -> Word32 -> Int
forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit
#endif
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *). Generator g m => (Int, Int) -> g -> m Int
uniformR (Int, Int)
a g
g = (Int, Int) -> g -> m Int
forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (Int, Int)
a g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => Int -> g -> m Int
uniformB Int
b g
g = (Word32 -> Int) -> Word32 -> g -> m Int
forall g (m :: * -> *) a.
(Generator g m, Integral a) =>
(Word32 -> a) -> Word32 -> g -> m a
uniform1B Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b) g
g
{-# INLINE uniformB #-}
instance (Variate a, Variate b) => Variate (a,b) where
uniform :: forall g (m :: * -> *). Generator g m => g -> m (a, b)
uniform g
g = (,) (a -> b -> (a, b)) -> m a -> m (b -> (a, b))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` g -> m a
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g m (b -> (a, b)) -> m b -> m (a, b)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` g -> m b
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
((a, b), (a, b)) -> g -> m (a, b)
uniformR ((a
x1,b
y1),(a
x2,b
y2)) g
g = (,) (a -> b -> (a, b)) -> m a -> m (b -> (a, b))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` (a, a) -> g -> m a
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (a
x1,a
x2) g
g m (b -> (a, b)) -> m b -> m (a, b)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` (b, b) -> g -> m b
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (b
y1,b
y2) g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *). Generator g m => (a, b) -> g -> m (a, b)
uniformB (a
b1,b
b2) g
g = (,) (a -> b -> (a, b)) -> m a -> m (b -> (a, b))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` a -> g -> m a
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB a
b1 g
g m (b -> (a, b)) -> m b -> m (a, b)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` b -> g -> m b
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB b
b2 g
g
{-# INLINE uniformB #-}
instance (Variate a, Variate b, Variate c) => Variate (a,b,c) where
uniform :: forall g (m :: * -> *). Generator g m => g -> m (a, b, c)
uniform g
g = (,,) (a -> b -> c -> (a, b, c)) -> m a -> m (b -> c -> (a, b, c))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` g -> m a
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g m (b -> c -> (a, b, c)) -> m b -> m (c -> (a, b, c))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` g -> m b
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g m (c -> (a, b, c)) -> m c -> m (a, b, c)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` g -> m c
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
((a, b, c), (a, b, c)) -> g -> m (a, b, c)
uniformR ((a
x1,b
y1,c
z1),(a
x2,b
y2,c
z2)) g
g =
(,,) (a -> b -> c -> (a, b, c)) -> m a -> m (b -> c -> (a, b, c))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` (a, a) -> g -> m a
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (a
x1,a
x2) g
g m (b -> c -> (a, b, c)) -> m b -> m (c -> (a, b, c))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` (b, b) -> g -> m b
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (b
y1,b
y2) g
g m (c -> (a, b, c)) -> m c -> m (a, b, c)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` (c, c) -> g -> m c
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (c
z1,c
z2) g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *).
Generator g m =>
(a, b, c) -> g -> m (a, b, c)
uniformB (a
b1,b
b2,c
b3) g
g = (,,) (a -> b -> c -> (a, b, c)) -> m a -> m (b -> c -> (a, b, c))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` a -> g -> m a
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB a
b1 g
g m (b -> c -> (a, b, c)) -> m b -> m (c -> (a, b, c))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` b -> g -> m b
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB b
b2 g
g m (c -> (a, b, c)) -> m c -> m (a, b, c)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` c -> g -> m c
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB c
b3 g
g
{-# INLINE uniformB #-}
instance (Variate a, Variate b, Variate c, Variate d) => Variate (a,b,c,d) where
uniform :: forall g (m :: * -> *). Generator g m => g -> m (a, b, c, d)
uniform g
g = (,,,) (a -> b -> c -> d -> (a, b, c, d))
-> m a -> m (b -> c -> d -> (a, b, c, d))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` g -> m a
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g m (b -> c -> d -> (a, b, c, d))
-> m b -> m (c -> d -> (a, b, c, d))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` g -> m b
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g m (c -> d -> (a, b, c, d)) -> m c -> m (d -> (a, b, c, d))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` g -> m c
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g m (d -> (a, b, c, d)) -> m d -> m (a, b, c, d)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` g -> m d
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
{-# INLINE uniform #-}
uniformR :: forall g (m :: * -> *).
Generator g m =>
((a, b, c, d), (a, b, c, d)) -> g -> m (a, b, c, d)
uniformR ((a
x1,b
y1,c
z1,d
t1),(a
x2,b
y2,c
z2,d
t2)) g
g =
(,,,) (a -> b -> c -> d -> (a, b, c, d))
-> m a -> m (b -> c -> d -> (a, b, c, d))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` (a, a) -> g -> m a
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (a
x1,a
x2) g
g m (b -> c -> d -> (a, b, c, d))
-> m b -> m (c -> d -> (a, b, c, d))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` (b, b) -> g -> m b
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (b
y1,b
y2) g
g m (c -> d -> (a, b, c, d)) -> m c -> m (d -> (a, b, c, d))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap`
(c, c) -> g -> m c
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (c
z1,c
z2) g
g m (d -> (a, b, c, d)) -> m d -> m (a, b, c, d)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` (d, d) -> g -> m d
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR (d
t1,d
t2) g
g
{-# INLINE uniformR #-}
uniformB :: forall g (m :: * -> *).
Generator g m =>
(a, b, c, d) -> g -> m (a, b, c, d)
uniformB (a
b1,b
b2,c
b3,d
b4) g
g = (,,,) (a -> b -> c -> d -> (a, b, c, d))
-> m a -> m (b -> c -> d -> (a, b, c, d))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` a -> g -> m a
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB a
b1 g
g m (b -> c -> d -> (a, b, c, d))
-> m b -> m (c -> d -> (a, b, c, d))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` b -> g -> m b
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB b
b2 g
g m (c -> d -> (a, b, c, d)) -> m c -> m (d -> (a, b, c, d))
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` c -> g -> m c
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB c
b3 g
g m (d -> (a, b, c, d)) -> m d -> m (a, b, c, d)
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
`ap` d -> g -> m d
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB d
b4 g
g
{-# INLINE uniformB #-}
uniformI8 :: Generator g m => g -> m Int8
uniformI8 :: forall g (m :: * -> *). Generator g m => g -> m Int8
uniformI8 = g -> m Int8
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformI8 #-}
uniformI16 :: Generator g m => g -> m Int16
uniformI16 :: forall g (m :: * -> *). Generator g m => g -> m Int16
uniformI16 = g -> m Int16
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformI16 #-}
uniformI32 :: Generator g m => g -> m Int32
uniformI32 :: forall g (m :: * -> *). Generator g m => g -> m Int32
uniformI32 = g -> m Int32
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformI32 #-}
uniformI64 :: Generator g m => g -> m Int64
uniformI64 :: forall g (m :: * -> *). Generator g m => g -> m Int64
uniformI64 = g -> m Int64
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformI64 #-}
uniformW8 :: Generator g m => g -> m Word8
uniformW8 :: forall g (m :: * -> *). Generator g m => g -> m Word8
uniformW8 = g -> m Word8
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformW8 #-}
uniformW16 :: Generator g m => g -> m Word16
uniformW16 :: forall g (m :: * -> *). Generator g m => g -> m Word16
uniformW16 = g -> m Word16
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformW16 #-}
uniformW32 :: Generator g m => g -> m Word32
uniformW32 :: forall g (m :: * -> *). Generator g m => g -> m Word32
uniformW32 = g -> m Word32
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformW32 #-}
uniformW64 :: Generator g m => g -> m Word64
uniformW64 :: forall g (m :: * -> *). Generator g m => g -> m Word64
uniformW64 = g -> m Word64
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformW64 #-}
uniformBool :: Generator g m => g -> m Bool
uniformBool :: forall g (m :: * -> *). Generator g m => g -> m Bool
uniformBool = g -> m Bool
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformBool #-}
uniformF :: Generator g m => g -> m Float
uniformF :: forall g (m :: * -> *). Generator g m => g -> m Float
uniformF = g -> m Float
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformF #-}
uniformD :: Generator g m => g -> m Double
uniformD :: forall g (m :: * -> *). Generator g m => g -> m Double
uniformD = g -> m Double
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform
{-# INLINE uniformD #-}
uniformRI8 :: Generator g m => (Int8, Int8) -> g -> m Int8
uniformRI8 :: forall g (m :: * -> *).
Generator g m =>
(Int8, Int8) -> g -> m Int8
uniformRI8 = (Int8, Int8) -> g -> m Int8
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRI8 #-}
uniformRI16 :: Generator g m => (Int16, Int16) -> g -> m Int16
uniformRI16 :: forall g (m :: * -> *).
Generator g m =>
(Int16, Int16) -> g -> m Int16
uniformRI16 = (Int16, Int16) -> g -> m Int16
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRI16 #-}
uniformRI32 :: Generator g m => (Int32, Int32) -> g -> m Int32
uniformRI32 :: forall g (m :: * -> *).
Generator g m =>
(Int32, Int32) -> g -> m Int32
uniformRI32 = (Int32, Int32) -> g -> m Int32
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRI32 #-}
uniformRI64 :: Generator g m => (Int64, Int64) -> g -> m Int64
uniformRI64 :: forall g (m :: * -> *).
Generator g m =>
(Int64, Int64) -> g -> m Int64
uniformRI64 = (Int64, Int64) -> g -> m Int64
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRI64 #-}
uniformRW8 :: Generator g m => (Word8, Word8) -> g -> m Word8
uniformRW8 :: forall g (m :: * -> *).
Generator g m =>
(Word8, Word8) -> g -> m Word8
uniformRW8 = (Word8, Word8) -> g -> m Word8
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRW8 #-}
uniformRW16 :: Generator g m => (Word16, Word16) -> g -> m Word16
uniformRW16 :: forall g (m :: * -> *).
Generator g m =>
(Word16, Word16) -> g -> m Word16
uniformRW16 = (Word16, Word16) -> g -> m Word16
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRW16 #-}
uniformRW32 :: Generator g m => (Word32, Word32) -> g -> m Word32
uniformRW32 :: forall g (m :: * -> *).
Generator g m =>
(Word32, Word32) -> g -> m Word32
uniformRW32 = (Word32, Word32) -> g -> m Word32
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRW32 #-}
uniformRW64 :: Generator g m => (Word64, Word64) -> g -> m Word64
uniformRW64 :: forall g (m :: * -> *).
Generator g m =>
(Word64, Word64) -> g -> m Word64
uniformRW64 = (Word64, Word64) -> g -> m Word64
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRW64 #-}
uniformRBool :: Generator g m => (Bool, Bool) -> g -> m Bool
uniformRBool :: forall g (m :: * -> *).
Generator g m =>
(Bool, Bool) -> g -> m Bool
uniformRBool = (Bool, Bool) -> g -> m Bool
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRBool #-}
uniformRF :: Generator g m => (Float, Float) -> g -> m Float
uniformRF :: forall g (m :: * -> *).
Generator g m =>
(Float, Float) -> g -> m Float
uniformRF = (Float, Float) -> g -> m Float
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRF #-}
uniformRD :: Generator g m => (Double, Double) -> g -> m Double
uniformRD :: forall g (m :: * -> *).
Generator g m =>
(Double, Double) -> g -> m Double
uniformRD = (Double, Double) -> g -> m Double
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
(a, a) -> g -> m a
uniformR
{-# INLINE uniformRD #-}
uniformBI8 :: Generator g m => Int8 -> g -> m Int8
uniformBI8 :: forall g (m :: * -> *). Generator g m => Int8 -> g -> m Int8
uniformBI8 = Int8 -> g -> m Int8
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBI8 #-}
uniformBI16 :: Generator g m => Int16 -> g -> m Int16
uniformBI16 :: forall g (m :: * -> *). Generator g m => Int16 -> g -> m Int16
uniformBI16 = Int16 -> g -> m Int16
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBI16 #-}
uniformBI32 :: Generator g m => Int32 -> g -> m Int32
uniformBI32 :: forall g (m :: * -> *). Generator g m => Int32 -> g -> m Int32
uniformBI32 = Int32 -> g -> m Int32
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBI32 #-}
uniformBI64 :: Generator g m => Int64 -> g -> m Int64
uniformBI64 :: forall g (m :: * -> *). Generator g m => Int64 -> g -> m Int64
uniformBI64 = Int64 -> g -> m Int64
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBI64 #-}
uniformBW8 :: Generator g m => Word8 -> g -> m Word8
uniformBW8 :: forall g (m :: * -> *). Generator g m => Word8 -> g -> m Word8
uniformBW8 = Word8 -> g -> m Word8
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBW8 #-}
uniformBW16 :: Generator g m => Word16 -> g -> m Word16
uniformBW16 :: forall g (m :: * -> *). Generator g m => Word16 -> g -> m Word16
uniformBW16 = Word16 -> g -> m Word16
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBW16 #-}
uniformBW32 :: Generator g m => Word32 -> g -> m Word32
uniformBW32 :: forall g (m :: * -> *). Generator g m => Word32 -> g -> m Word32
uniformBW32 = Word32 -> g -> m Word32
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBW32 #-}
uniformBW64 :: Generator g m => Word64 -> g -> m Word64
uniformBW64 :: forall g (m :: * -> *). Generator g m => Word64 -> g -> m Word64
uniformBW64 = Word64 -> g -> m Word64
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBW64 #-}
uniformBBool :: Generator g m => Bool -> g -> m Bool
uniformBBool :: forall g (m :: * -> *). Generator g m => Bool -> g -> m Bool
uniformBBool = Bool -> g -> m Bool
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBBool #-}
uniformBF :: Generator g m => Float -> g -> m Float
uniformBF :: forall g (m :: * -> *). Generator g m => Float -> g -> m Float
uniformBF = Float -> g -> m Float
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBF #-}
uniformBD :: Generator g m => Double -> g -> m Double
uniformBD :: forall g (m :: * -> *). Generator g m => Double -> g -> m Double
uniformBD = Double -> g -> m Double
forall a g (m :: * -> *).
(Variate a, Generator g m) =>
a -> g -> m a
uniformB
{-# INLINE uniformBD #-}
sub :: (Integral a, Integral (Unsigned a)) => a -> a -> Unsigned a
sub :: forall a.
(Integral a, Integral (Unsigned a)) =>
a -> a -> Unsigned a
sub a
x a
y = a -> Unsigned a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x Unsigned a -> Unsigned a -> Unsigned a
forall a. Num a => a -> a -> a
- a -> Unsigned a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
y
{-# INLINE sub #-}
add :: (Integral a, Integral (Unsigned a)) => a -> Unsigned a -> a
add :: forall a.
(Integral a, Integral (Unsigned a)) =>
a -> Unsigned a -> a
add a
m Unsigned a
x = a
m a -> a -> a
forall a. Num a => a -> a -> a
+ Unsigned a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Unsigned a
x
{-# INLINE add #-}
wordsTo64Bit :: Integral a => Word32 -> Word32 -> a
wordsTo64Bit :: forall a. Integral a => Word32 -> Word32 -> a
wordsTo64Bit Word32
x Word32
y =
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
y :: Word64)
{-# INLINE wordsTo64Bit #-}
wordToBool :: Word32 -> Bool
wordToBool :: Word32 -> Bool
wordToBool Word32
i = (Word32
i Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
1) Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word32
0
{-# INLINE wordToBool #-}
wordToFloat :: Word32 -> Float
wordToFloat :: Word32 -> Float
wordToFloat Word32
x = (Int32 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
i Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m_inv_32) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m_inv_33
where m_inv_33 :: Float
m_inv_33 = Float
1.16415321826934814453125e-10
m_inv_32 :: Float
m_inv_32 = Float
2.3283064365386962890625e-10
i :: Int32
i = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x :: Int32
{-# INLINE wordToFloat #-}
wordsToDouble :: Word32 -> Word32 -> Double
wordsToDouble :: Word32 -> Word32 -> Double
wordsToDouble Word32
x Word32
y = (Int32 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
u Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
m_inv_32 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (Double
0.5 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
m_inv_53) Double -> Double -> Double
forall a. Num a => a -> a -> a
+
Int32 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32
v Int32 -> Int32 -> Int32
forall a. Bits a => a -> a -> a
.&. Int32
0xFFFFF) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
m_inv_52)
where m_inv_52 :: Double
m_inv_52 = Double
2.220446049250313080847263336181640625e-16
m_inv_53 :: Double
m_inv_53 = Double
1.1102230246251565404236316680908203125e-16
m_inv_32 :: Double
m_inv_32 = Double
2.3283064365386962890625e-10
u :: Int32
u = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x :: Int32
v :: Int32
v = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
y :: Int32
{-# INLINE wordsToDouble #-}
sysRandom :: IO Word64
sysRandom :: IO Word64
sysRandom = do
ByteString
bs <- Int -> IO ByteString
getEntropy Int
8
ByteString -> (CString -> IO Word64) -> IO Word64
forall a. ByteString -> (CString -> IO a) -> IO a
useAsCString ByteString
bs ((CString -> IO Word64) -> IO Word64)
-> (CString -> IO Word64) -> IO Word64
forall a b. (a -> b) -> a -> b
$ Ptr Word64 -> IO Word64
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word64 -> IO Word64)
-> (CString -> Ptr Word64) -> CString -> IO Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CString -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr
uniformRange
:: (Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a))
=> (a,a) -> g -> m a
uniformRange :: forall g (m :: * -> *) a.
(Generator g m, Integral a, Variate a, Integral (Unsigned a),
Bounded (Unsigned a), Variate (Unsigned a)) =>
(a, a) -> g -> m a
uniformRange (a
x1,a
x2) g
g
| Unsigned a
n Unsigned a -> Unsigned a -> Bool
forall a. Eq a => a -> a -> Bool
== Unsigned a
0 = g -> m a
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
| Bool
otherwise = m a
loop
where
(a
i, a
j) | a
x1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
x2 = (a
x1, a
x2)
| Bool
otherwise = (a
x2, a
x1)
n :: Unsigned a
n = Unsigned a
1 Unsigned a -> Unsigned a -> Unsigned a
forall a. Num a => a -> a -> a
+ a -> a -> Unsigned a
forall a.
(Integral a, Integral (Unsigned a)) =>
a -> a -> Unsigned a
sub a
j a
i
buckets :: Unsigned a
buckets = Unsigned a
forall a. Bounded a => a
maxBound Unsigned a -> Unsigned a -> Unsigned a
forall a. Integral a => a -> a -> a
`div` Unsigned a
n
maxN :: Unsigned a
maxN = Unsigned a
buckets Unsigned a -> Unsigned a -> Unsigned a
forall a. Num a => a -> a -> a
* Unsigned a
n
loop :: m a
loop = do Unsigned a
x <- g -> m (Unsigned a)
forall a g (m :: * -> *). (Variate a, Generator g m) => g -> m a
uniform g
g
if Unsigned a
x Unsigned a -> Unsigned a -> Bool
forall a. Ord a => a -> a -> Bool
< Unsigned a
maxN then 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
$! a -> Unsigned a -> a
forall a.
(Integral a, Integral (Unsigned a)) =>
a -> Unsigned a -> a
add a
i (Unsigned a
x Unsigned a -> Unsigned a -> Unsigned a
forall a. Integral a => a -> a -> a
`div` Unsigned a
buckets)
else m a
loop
{-# INLINE uniformRange #-}
type family Unsigned a :: Data.Kind.Type
type instance Unsigned Int8 = Word8
type instance Unsigned Int16 = Word16
type instance Unsigned Int32 = Word32
type instance Unsigned Int64 = Word64
type instance Unsigned Word8 = Word8
type instance Unsigned Word16 = Word16
type instance Unsigned Word32 = Word32
type instance Unsigned Word64 = Word64
#if (WORD_SIZE_IN_BITS < 64) && (__GLASGOW_HASKELL__ == 706)
type instance Unsigned Int = Word32
type instance Unsigned Word = Word32
#else
type instance Unsigned Int = Word
type instance Unsigned Word = Word
#endif