{-# Language CPP, BangPatterns, ScopedTypeVariables #-}
-- |
-- Module    : System.Random.TF.Instances
-- Copyright : (c) 2012-2013 Michał Pałka
-- License   : BSD3
--
-- Maintainer  : michal.palka@chalmers.se
-- Stability   : experimental
-- Portability : portable
--
-- This module defines alternative 'Random' instances for
-- common integral types, which make use of 
-- the 'System.Random.TF.Gen.RandomGen' class from "System.Random.TF.Gen".

module System.Random.TF.Instances
 (Random (..), randomEnum) where

import Data.Bits
import Data.Int
import Data.Word

import System.Random.TF.Gen

#if !MIN_VERSION_base(4,5,0)
unsafeShiftR :: Bits a => a -> Int -> a
unsafeShiftR = shiftR

unsafeShiftL :: Bits a => a -> Int -> a
unsafeShiftL = shiftL
#endif

myUnfoldr :: (t -> (a, t)) -> t -> [a]
myUnfoldr :: forall t a. (t -> (a, t)) -> t -> [a]
myUnfoldr t -> (a, t)
f t
g = a
x' forall a. a -> [a] -> [a]
: forall t a. (t -> (a, t)) -> t -> [a]
myUnfoldr t -> (a, t)
f t
g'
  where
  (a
x', t
g') = t -> (a, t)
f t
g

class Random a where
  randomR :: RandomGen g => (a,a) -> g -> (a,g)

  random  :: RandomGen g => g -> (a, g)

  randomRs :: RandomGen g => (a,a) -> g -> [a]
  randomRs (a, a)
ival g
g = forall t a. (t -> (a, t)) -> t -> [a]
myUnfoldr (forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (a, a)
ival) g
g

  randoms  :: RandomGen g => g -> [a]
  randoms  g
g      = forall t a. (t -> (a, t)) -> t -> [a]
myUnfoldr forall a g. (Random a, RandomGen g) => g -> (a, g)
random g
g
{-
  randomRIO :: (a,a) -> IO a

  randomIO  :: IO a
-}

boundsWrap :: Integral a => (a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap :: forall a g.
Integral a =>
(a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap a -> g -> (a, g)
f (a
l, a
h) g
rng
  | a
l forall a. Eq a => a -> a -> Bool
== a
h    = (a
l, g
rng)
  | a
l forall a. Ord a => a -> a -> Bool
> a
h     = forall {t} {a} {b}. (t -> a) -> (t, b) -> (a, b)
mapFst (a
hforall a. Num a => a -> a -> a
+) forall a b. (a -> b) -> a -> b
$ a -> g -> (a, g)
f (a
l forall a. Num a => a -> a -> a
- a
h) g
rng
  | Bool
otherwise = forall {t} {a} {b}. (t -> a) -> (t, b) -> (a, b)
mapFst (a
lforall a. Num a => a -> a -> a
+) forall a b. (a -> b) -> a -> b
$ a -> g -> (a, g)
f (a
h forall a. Num a => a -> a -> a
- a
l) g
rng
  where mapFst :: (t -> a) -> (t, b) -> (a, b)
mapFst t -> a
g (t
x, b
y) = (t -> a
g t
x, b
y)

randomWord32 :: RandomGen g => (Word32, Word32) -> g -> (Word32, g)
randomWord32 :: forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
randomWord32 (Word32
l, Word32
h) g
rng = forall a g.
Integral a =>
(a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap forall g. RandomGen g => Word32 -> g -> (Word32, g)
randomWord32' (Word32
l, Word32
h) g
rng

randomInt32 :: RandomGen g => (Int32, Int32) -> g -> (Int32, g)
randomInt32 :: forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
randomInt32 (Int32
l, Int32
h) g
rng = forall a g.
Integral a =>
(a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap forall {b} {a} {a}.
(RandomGen b, Integral a, Num a) =>
a -> b -> (a, b)
randomInt32' (Int32
l, Int32
h) g
rng
  where
  randomInt32' :: a -> b -> (a, b)
randomInt32' a
m b
r = case forall g. RandomGen g => Word32 -> g -> (Word32, g)
randomWord32' (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
m) b
r of
                       (Word32
x, b
r') -> (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, b
r')

word32Mask :: Word32 -> Word32
word32Mask :: Word32 -> Word32
word32Mask Word32
w =
  (((((Word32
w forall {a}. Bits a => a -> Int -> a
.>. Int
1) forall {a}. Bits a => a -> Int -> a
.>. Int
2) forall {a}. Bits a => a -> Int -> a
.>. Int
4) forall {a}. Bits a => a -> Int -> a
.>. Int
8) forall {a}. Bits a => a -> Int -> a
.>. Int
16)
  where
  a
w .>. :: a -> Int -> a
.>. Int
n = a
w forall a. Bits a => a -> a -> a
.|. (a
w forall {a}. Bits a => a -> Int -> a
`unsafeShiftR` Int
n)

-- Inspired by Java's java.util.Random.
-- This version avoids division modulo.
-- Returns a random number from range [0..k-1], or from the full range if k = 0.
{-# INLINE randomWord32' #-}
randomWord32' :: RandomGen g => Word32 -> g -> (Word32, g)
randomWord32' :: forall g. RandomGen g => Word32 -> g -> (Word32, g)
randomWord32' Word32
k
  -- Case 1: k is the maxBound.
  | Word32
k' forall a. Eq a => a -> a -> Bool
== Word32
0       = forall g. RandomGen g => g -> (Word32, g)
next
  -- Case 2: k' is a power of two; k is a bit mask.
  | Word32
k' forall a. Bits a => a -> a -> a
.&. Word32
k forall a. Eq a => a -> a -> Bool
== Word32
0 = \g
rng ->
      case forall g. RandomGen g => g -> (Word32, g)
next g
rng of
        (Word32
x, g
rng') -> (Word32
x forall a. Bits a => a -> a -> a
.&. Word32
k, g
rng')
  -- Case 3: The general case. Case 3 subsumes Case 2,
  -- and Case 2 subsumes Case 1. Cases 1 and 2 are
  -- there for efficiency.
  | Bool
otherwise     = forall g. RandomGen g => g -> (Word32, g)
loop
  where
  k' :: Word32
k' = Word32
k forall a. Num a => a -> a -> a
+ Word32
1
  mask :: Word32
mask = Word32 -> Word32
word32Mask Word32
k
  loop :: t -> (Word32, t)
loop t
rng
    | Word32
x' forall a. Ord a => a -> a -> Bool
<= Word32
k   = (Word32
x', t
rng')
    | Bool
otherwise = t -> (Word32, t)
loop t
rng'
    where
    (Word32
x, t
rng') = forall g. RandomGen g => g -> (Word32, g)
next t
rng
    x' :: Word32
x' = Word32
x forall a. Bits a => a -> a -> a
.&. Word32
mask

makeWord64 :: Word32 -> Word32 -> Word64
makeWord64 :: Word32 -> Word32 -> Word64
makeWord64 Word32
w1 Word32
w2 = Word64
w1' forall {a}. Bits a => a -> Int -> a
`unsafeShiftL` Int
32 forall a. Bits a => a -> a -> a
.|. Word64
w2'
  where
  w1', w2' :: Word64
  w1' :: Word64
w1' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
w1
  w2' :: Word64
w2' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
w2

randomWord64 :: RandomGen g => (Word64, Word64) -> g -> (Word64, g)
randomWord64 :: forall g. RandomGen g => (Word64, Word64) -> g -> (Word64, g)
randomWord64 (Word64
l, Word64
h) g
rng = forall a g.
Integral a =>
(a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap forall g. RandomGen g => Word64 -> g -> (Word64, g)
randomWord64' (Word64
l, Word64
h) g
rng

randomInt64 :: RandomGen g => (Int64, Int64) -> g -> (Int64, g)
randomInt64 :: forall g. RandomGen g => (Int64, Int64) -> g -> (Int64, g)
randomInt64 (Int64
l, Int64
h) g
rng = forall a g.
Integral a =>
(a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap forall {b} {a} {a}.
(RandomGen b, Integral a, Num a) =>
a -> b -> (a, b)
randomInt64' (Int64
l, Int64
h) g
rng
  where
  randomInt64' :: a -> b -> (a, b)
randomInt64' a
m b
r = case forall g. RandomGen g => Word64 -> g -> (Word64, g)
randomWord64' (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
m) b
r of
                       (Word64
x, b
r') -> (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x, b
r')

-- Works similarly to randomWord32'
randomWord64' :: RandomGen g => Word64 -> g -> (Word64, g)
randomWord64' :: forall g. RandomGen g => Word64 -> g -> (Word64, g)
randomWord64' Word64
k
  -- Case 1: The range fits in 32 bits.
  | Word64
k forall a. Ord a => a -> a -> Bool
<= Word64
m32      = \g
rng ->
    case forall g. RandomGen g => Word32 -> g -> (Word32, g)
randomWord32' (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
k) g
rng of
      (Word32
x, g
rng') -> (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
rng')
  -- Case 2: (l,h) is the full range. This case should
  -- probably be removed
  | Word64
k' forall a. Eq a => a -> a -> Bool
== Word64
0       = \g
rng ->
    let !(Word32
x1, g
rng')  = forall g. RandomGen g => g -> (Word32, g)
next g
rng
        !(Word32
x2, g
rng'') = forall g. RandomGen g => g -> (Word32, g)
next g
rng'
    in (Word32 -> Word32 -> Word64
makeWord64 Word32
x1 Word32
x2, g
rng'')
  -- Case 3: k' is a power of two; k is a bit mask.
  | Word64
k' forall a. Bits a => a -> a -> a
.&. Word64
k forall a. Eq a => a -> a -> Bool
== Word64
0 = \g
rng ->
    let !(Word32
x1, g
rng')  = forall g. RandomGen g => g -> (Word32, g)
next g
rng
        !(Word32
x2, g
rng'') = forall g. RandomGen g => g -> (Word32, g)
next g
rng'
    in (Word32 -> Word32 -> Word64
makeWord64 Word32
x1 Word32
x2 forall a. Bits a => a -> a -> a
.&. Word64
k, g
rng'')
  -- Case 4: The general case. Case 4 subsumes Cases 1 and 3,
  -- and Case 3 subsumes Case 2. Cases 1, 2 and 3 are
  -- there for efficiency.
  | Bool
otherwise     = forall {t}. RandomGen t => t -> (Word64, t)
loop
  where
  m32 :: Word64
  m32 :: Word64
m32 = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Word32)
  k' :: Word64
k' = Word64
k forall a. Num a => a -> a -> a
+ Word64
1
  mask :: Word32
mask = Word32 -> Word32
word32Mask (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Word64
k forall {a}. Bits a => a -> Int -> a
`unsafeShiftR` Int
32)
  loop :: t -> (Word64, t)
loop t
rng
    | Word64
x forall a. Ord a => a -> a -> Bool
<= Word64
k    = (Word64
x, t
rng'')
    | Bool
otherwise = t -> (Word64, t)
loop t
rng''
    where
    (Word32
x1, t
rng')  = forall g. RandomGen g => g -> (Word32, g)
next t
rng
    (Word32
x2, t
rng'') = forall g. RandomGen g => g -> (Word32, g)
next t
rng'
    x :: Word64
x  = Word32 -> Word32 -> Word64
makeWord64 (Word32
x1 forall a. Bits a => a -> a -> a
.&. Word32
mask) Word32
x2

-- Returns the most significant word and the number of extra words.
-- x must be non-negative
getShiftAndLead :: (Integral a, Bits a) => a -> (Int, Word32)
getShiftAndLead :: forall a. (Integral a, Bits a) => a -> (Int, Word32)
getShiftAndLead !a
x = forall {t} {b} {t}.
(Integral t, Num b, Num t, Bits t) =>
t -> t -> (t, b)
cWords a
x Int
0
  where
  cWords :: t -> t -> (t, b)
cWords !t
x !t
c
    | t
x' forall a. Eq a => a -> a -> Bool
== t
0   = (t
c, forall a b. (Integral a, Num b) => a -> b
fromIntegral t
x)
    | Bool
otherwise = t -> t -> (t, b)
cWords t
x' (t
cforall a. Num a => a -> a -> a
+t
1)
    where
    x' :: t
x' = t
x forall {a}. Bits a => a -> Int -> a
`unsafeShiftR` Int
32

randomInteger :: RandomGen g => (Integer, Integer) -> g -> (Integer, g)
randomInteger :: forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
randomInteger (Integer
l, Integer
h) g
rng = forall a g.
Integral a =>
(a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
boundsWrap forall g. RandomGen g => Integer -> g -> (Integer, g)
randomInteger' (Integer
l, Integer
h) g
rng

{-# INLINE randomInteger' #-}
randomInteger' :: forall g. RandomGen g => Integer -> g -> (Integer, g)
randomInteger' :: forall g. RandomGen g => Integer -> g -> (Integer, g)
randomInteger' Integer
k g
rng
  | Integer
k forall a. Ord a => a -> a -> Bool
< Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
64  = case forall g. RandomGen g => Word64 -> g -> (Word64, g)
randomWord64' (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
k) g
rng of
                  (Word64
x, g
rng') -> (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x, g
rng')
  | Bool
otherwise = g -> (Integer, g)
loop g
rng
  where
  (Int
w, Word32
l) = forall a. (Integral a, Bits a) => a -> (Int, Word32)
getShiftAndLead Integer
k
  -- Constructing Integers is very expensive, so it is better
  -- to do it from Word64s than from Word32s.
  construct :: g -> (Integer, g)
construct g
rng
    | forall a. Integral a => a -> Bool
even Int
w    = Integer -> Int -> g -> (Integer, g)
construct' (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
lx) Int
w   g
rng'
    | Bool
otherwise = Integer -> Int -> g -> (Integer, g)
construct' (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x) (Int
wforall a. Num a => a -> a -> a
-Int
1) g
rng''
    where
    (Word32
lx, g
rng')  = forall g. RandomGen g => Word32 -> g -> (Word32, g)
randomWord32' Word32
l g
rng
    (Word32
x2, g
rng'') = forall g. RandomGen g => g -> (Word32, g)
next g
rng'
    x :: Word64
x  = Word32 -> Word32 -> Word64
makeWord64 Word32
lx Word32
x2
  construct' :: Integer -> Int -> g -> (Integer, g)
  construct' :: Integer -> Int -> g -> (Integer, g)
construct' !Integer
a Int
0 g
rng = (Integer
a, g
rng)
  construct' !Integer
a Int
n g
rng =
    Integer -> Int -> g -> (Integer, g)
construct' (Integer
a forall {a}. Bits a => a -> Int -> a
`shiftL` Int
64 forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x) (Int
nforall a. Num a => a -> a -> a
-Int
2) g
rng''
    where
    (Word32
x1, g
rng')  = forall g. RandomGen g => g -> (Word32, g)
next g
rng
    (Word32
x2, g
rng'') = forall g. RandomGen g => g -> (Word32, g)
next g
rng'
    x :: Word64
x  = Word32 -> Word32 -> Word64
makeWord64 Word32
x1 Word32
x2
  loop :: g -> (Integer, g)
loop g
rng
    | Integer
x forall a. Ord a => a -> a -> Bool
<= Integer
k   = (Integer
x, g
rng')
    | Bool
otherwise = g -> (Integer, g)
loop g
rng'
    where
    (Integer
x, g
rng') = g -> (Integer, g)
construct g
rng

randomBounded :: (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded :: forall g a. (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded = forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (forall a. Bounded a => a
minBound, forall a. Bounded a => a
maxBound)

instance Random Int where
  randomR :: forall g. RandomGen g => (Int, Int) -> g -> (Int, g)
randomR (Int
a, Int
b) g
rng = (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
x, g
rng')
    where !(Int64
x, g
rng') = forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a :: Int64, forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b) g
rng
  random :: forall g. RandomGen g => g -> (Int, g)
random  = forall g a. (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded

randomEnum :: (Enum a, RandomGen g) => (a, a) -> g -> (a, g)
randomEnum :: forall a g. (Enum a, RandomGen g) => (a, a) -> g -> (a, g)
randomEnum (a
a,a
b) g
g = 
  case forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (forall a. Enum a => a -> Int
fromEnum a
a, forall a. Enum a => a -> Int
fromEnum a
b) g
g of
    (Int
x, g
g') -> (forall a. Enum a => Int -> a
toEnum Int
x, g
g')

instance Random Char where
  randomR :: forall g. RandomGen g => (Char, Char) -> g -> (Char, g)
randomR = forall a g. (Enum a, RandomGen g) => (a, a) -> g -> (a, g)
randomEnum
  random :: forall g. RandomGen g => g -> (Char, g)
random  = forall g a. (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded

instance Random Bool where
  randomR :: forall g. RandomGen g => (Bool, Bool) -> g -> (Bool, g)
randomR = forall a g. (Enum a, RandomGen g) => (a, a) -> g -> (a, g)
randomEnum
  random :: forall g. RandomGen g => g -> (Bool, g)
random  = forall g a. (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded

-- For random Integers we use the range of Int
instance Random Integer where
  randomR :: forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
randomR = forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
randomInteger
  random :: forall g. RandomGen g => g -> (Integer, g)
random  = forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
minBound::Int), forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
maxBound::Int))

instance Random Word32 where
  randomR :: forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
randomR = forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
randomWord32
  -- Optimised version
  random :: forall g. RandomGen g => g -> (Word32, g)
random  = forall g. RandomGen g => g -> (Word32, g)
next

instance Random Word64 where
  randomR :: forall g. RandomGen g => (Word64, Word64) -> g -> (Word64, g)
randomR = forall g. RandomGen g => (Word64, Word64) -> g -> (Word64, g)
randomWord64
  random :: forall {t}. RandomGen t => t -> (Word64, t)
random  = forall g a. (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded

instance Random Int32 where
  randomR :: forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
randomR = forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
randomInt32
  -- Optimised version
  random :: forall g. RandomGen g => g -> (Int32, g)
random g
g = let (Word32
x, g
g') = forall g. RandomGen g => g -> (Word32, g)
next g
g in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')

instance Random Int64 where
  randomR :: forall g. RandomGen g => (Int64, Int64) -> g -> (Int64, g)
randomR = forall g. RandomGen g => (Int64, Int64) -> g -> (Int64, g)
randomInt64
  random :: forall g. RandomGen g => g -> (Int64, g)
random  = forall g a. (RandomGen g, Random a, Bounded a) => g -> (a, g)
randomBounded

instance Random Word8 where
  randomR :: forall g. RandomGen g => (Word8, Word8) -> g -> (Word8, g)
randomR (Word8
l, Word8
h) g
g =
    let (Word32
x, g
g') = forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
randomWord32 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
l, forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
h) g
g
    in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')
  -- Optimised version
  random :: forall g. RandomGen g => g -> (Word8, g)
random g
g = let (Word32
x, g
g') = forall g. RandomGen g => g -> (Word32, g)
next g
g in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')

instance Random Int8 where
  randomR :: forall g. RandomGen g => (Int8, Int8) -> g -> (Int8, g)
randomR (Int8
l, Int8
h) g
g =
    let (Int32
x, g
g') = forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
randomInt32 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int8
l, forall a b. (Integral a, Num b) => a -> b
fromIntegral Int8
h) g
g
    in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
x, g
g')
  -- Optimised version
  random :: forall g. RandomGen g => g -> (Int8, g)
random g
g = let (Word32
x, g
g') = forall g. RandomGen g => g -> (Word32, g)
next g
g in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')

instance Random Word16 where
  randomR :: forall g. RandomGen g => (Word16, Word16) -> g -> (Word16, g)
randomR (Word16
l, Word16
h) g
g =
    let (Word32
x, g
g') = forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
randomWord32 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
l, forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
h) g
g
    in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')
  -- Optimised version
  random :: forall g. RandomGen g => g -> (Word16, g)
random g
g = let (Word32
x, g
g') = forall g. RandomGen g => g -> (Word32, g)
next g
g in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')

instance Random Int16 where
  randomR :: forall g. RandomGen g => (Int16, Int16) -> g -> (Int16, g)
randomR (Int16
l, Int16
h) g
g =
    let (Int32
x, g
g') = forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
randomInt32 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
l, forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
h) g
g
    in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
x, g
g')
  -- Optimised version
  random :: forall g. RandomGen g => g -> (Int16, g)
random g
g = let (Word32
x, g
g') = forall g. RandomGen g => g -> (Word32, g)
next g
g in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x, g
g')