    {-# 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' a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : (t -> (a, t)) -> t -> [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 = (g -> (a, g)) -> g -> [a]
    forall t a. (t -> (a, t)) -> t -> [a]
    myUnfoldr ((a, a) -> g -> (a, g)
    forall g. RandomGen g => (a, a) -> g -> (a, g)
    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      = (g -> (a, g)) -> g -> [a]
    forall t a. (t -> (a, t)) -> t -> [a]
    myUnfoldr g -> (a, g)
    forall g. RandomGen g => g -> (a, g)
    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 a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    h    = (a
    l, g
    rng)
      | a
    l a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    h     = (a -> a) -> (a, g) -> (a, g)
    forall {t} {a} {b}. (t -> a) -> (t, b) -> (a, b)
    mapFst (a
    ha -> a -> a
    forall a. Num a => a -> a -> a
    +) ((a, g) -> (a, g)) -> (a, g) -> (a, g)
    forall a b. (a -> b) -> a -> b
    $ a -> g -> (a, g)
    f (a
    l a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    h) g
    rng
      | Bool
    otherwise = (a -> a) -> (a, g) -> (a, g)
    forall {t} {a} {b}. (t -> a) -> (t, b) -> (a, b)
    mapFst (a
    la -> a -> a
    forall a. Num a => a -> a -> a
    +) ((a, g) -> (a, g)) -> (a, g) -> (a, g)
    forall a b. (a -> b) -> a -> b
    $ a -> g -> (a, g)
    f (a
    h a -> a -> a
    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 = (Word32 -> g -> (Word32, g))
    -> (Word32, Word32) -> g -> (Word32, g)
    forall a g.
    Integral a =>
    (a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
    boundsWrap Word32 -> g -> (Word32, g)
    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 = (Int32 -> g -> (Int32, g)) -> (Int32, Int32) -> g -> (Int32, g)
    forall a g.
    Integral a =>
    (a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
    boundsWrap Int32 -> g -> (Int32, g)
    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 Word32 -> b -> (Word32, b)
    forall g. RandomGen g => Word32 -> g -> (Word32, g)
    randomWord32' (a -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    m) b
    r of
                           (Word32
    x, b
    r') -> (Word32 -> a
    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 Word32 -> Int -> Word32
    forall {a}. Bits a => a -> Int -> a
    .>. Int
    1) Word32 -> Int -> Word32
    forall {a}. Bits a => a -> Int -> a
    .>. Int
    2) Word32 -> Int -> Word32
    forall {a}. Bits a => a -> Int -> a
    .>. Int
    4) Word32 -> Int -> Word32
    forall {a}. Bits a => a -> Int -> a
    .>. Int
    8) Word32 -> Int -> Word32
    forall {a}. Bits a => a -> Int -> a
    .>. Int
    16)
      where
      a
    w .>. :: a -> Int -> a
    .>. Int
    n = a
    w a -> a -> a
    forall a. Bits a => a -> a -> a
    .|. (a
    w a -> Int -> a
    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' Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0       = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next
      -- Case 2: k' is a power of two; k is a bit mask.
      | Word32
    k' Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32
    k Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0 = \g
    rng ->
          case g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    rng of
            (Word32
    x, g
    rng') -> (Word32
    x Word32 -> Word32 -> Word32
    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     = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    loop
      where
      k' :: Word32
    k' = Word32
    k Word32 -> Word32 -> Word32
    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' Word32 -> Word32 -> Bool
    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') = t -> (Word32, t)
    forall g. RandomGen g => g -> (Word32, g)
    next t
    rng
        x' :: Word32
    x' = Word32
    x Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32
    mask

    makeWord64 :: Word32 -> Word32 -> Word64
    makeWord64 :: Word32 -> Word32 -> Word64
    makeWord64 Word32
    w1 Word32
    w2 = Word64
    w1' Word64 -> Int -> Word64
    forall {a}. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    32 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    w2'
      where
      w1', w2' :: Word64
      w1' :: Word64
    w1' = Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    w1
      w2' :: Word64
    w2' = Word32 -> Word64
    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 = (Word64 -> g -> (Word64, g))
    -> (Word64, Word64) -> g -> (Word64, g)
    forall a g.
    Integral a =>
    (a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
    boundsWrap Word64 -> g -> (Word64, g)
    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 = (Int64 -> g -> (Int64, g)) -> (Int64, Int64) -> g -> (Int64, g)
    forall a g.
    Integral a =>
    (a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
    boundsWrap Int64 -> g -> (Int64, g)
    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 Word64 -> b -> (Word64, b)
    forall g. RandomGen g => Word64 -> g -> (Word64, g)
    randomWord64' (a -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    m) b
    r of
                           (Word64
    x, b
    r') -> (Word64 -> a
    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 Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word64
    m32      = \g
    rng ->
        case Word32 -> g -> (Word32, g)
    forall g. RandomGen g => Word32 -> g -> (Word32, g)
    randomWord32' (Word64 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word64
    k) g
    rng of
          (Word32
    x, g
    rng') -> (Word32 -> Word64
    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' Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0       = \g
    rng ->
        let !(Word32
    x1, g
    rng')  = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    rng
            !(Word32
    x2, g
    rng'') = g -> (Word32, g)
    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' Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Word64
    k Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0 = \g
    rng ->
        let !(Word32
    x1, g
    rng')  = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    rng
            !(Word32
    x2, g
    rng'') = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    rng'
        in (Word32 -> Word32 -> Word64
    makeWord64 Word32
    x1 Word32
    x2 Word64 -> Word64 -> Word64
    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     = g -> (Word64, g)
    forall {t}. RandomGen t => t -> (Word64, t)
    loop
      where
      m32 :: Word64
      m32 :: Word64
    m32 = Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32
    forall a. Bounded a => a
    maxBound :: Word32)
      k' :: Word64
    k' = Word64
    k Word64 -> Word64 -> Word64
    forall a. Num a => a -> a -> a
    + Word64
    1
      mask :: Word32
    mask = Word32 -> Word32
    word32Mask (Word64 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word64 -> Word32) -> Word64 -> Word32
    forall a b. (a -> b) -> a -> b
    $ Word64
    k Word64 -> Int -> Word64
    forall {a}. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    32)
      loop :: t -> (Word64, t)
    loop t
    rng
        | Word64
    x Word64 -> Word64 -> Bool
    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')  = t -> (Word32, t)
    forall g. RandomGen g => g -> (Word32, g)
    next t
    rng
        (Word32
    x2, t
    rng'') = t -> (Word32, t)
    forall g. RandomGen g => g -> (Word32, g)
    next t
    rng'
        x :: Word64
    x  = Word32 -> Word32 -> Word64
    makeWord64 (Word32
    x1 Word32 -> Word32 -> Word32
    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 = a -> Int -> (Int, Word32)
    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' t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    0   = (t
    c, t -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral t
    x)
        | Bool
    otherwise = t -> t -> (t, b)
    cWords t
    x' (t
    ct -> t -> t
    forall a. Num a => a -> a -> a
    +t
    1)
        where
        x' :: t
    x' = t
    x t -> Int -> t
    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 = (Integer -> g -> (Integer, g))
    -> (Integer, Integer) -> g -> (Integer, g)
    forall a g.
    Integral a =>
    (a -> g -> (a, g)) -> (a, a) -> g -> (a, g)
    boundsWrap Integer -> g -> (Integer, g)
    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 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    2Integer -> Integer -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    ^Integer
    64  = case Word64 -> g -> (Word64, g)
    forall g. RandomGen g => Word64 -> g -> (Word64, g)
    randomWord64' (Integer -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    k) g
    rng of
                      (Word64
    x, g
    rng') -> (Word64 -> Integer
    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) = Integer -> (Int, Word32)
    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
        | Int -> Bool
    forall a. Integral a => a -> Bool
    even Int
    w    = Integer -> Int -> g -> (Integer, g)
    construct' (Word32 -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    lx) Int
    w   g
    rng'
        | Bool
    otherwise = Integer -> Int -> g -> (Integer, g)
    construct' (Word64 -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word64
    x) (Int
    wInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) g
    rng''
        where
        (Word32
    lx, g
    rng')  = Word32 -> g -> (Word32, g)
    forall g. RandomGen g => Word32 -> g -> (Word32, g)
    randomWord32' Word32
    l g
    rng
        (Word32
    x2, g
    rng'') = g -> (Word32, g)
    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 Integer -> Int -> Integer
    forall {a}. Bits a => a -> Int -> a
    `shiftL` Int
    64 Integer -> Integer -> Integer
    forall a. Bits a => a -> a -> a
    .|. Word64 -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word64
    x) (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    2) g
    rng''
        where
        (Word32
    x1, g
    rng')  = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    rng
        (Word32
    x2, g
    rng'') = g -> (Word32, g)
    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 Integer -> Integer -> Bool
    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 = (a, a) -> g -> (a, g)
    forall g. RandomGen g => (a, a) -> g -> (a, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (a
    forall a. Bounded a => a
    minBound, a
    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 = (Int64 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    x, g
    rng')
        where !(Int64
    x, g
    rng') = (Int64, Int64) -> g -> (Int64, g)
    forall g. RandomGen g => (Int64, Int64) -> g -> (Int64, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    a :: Int64, Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    b) g
    rng
      random :: forall g. RandomGen g => g -> (Int, g)
    random  = g -> (Int, g)
    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 (Int, Int) -> g -> (Int, g)
    forall g. RandomGen g => (Int, Int) -> g -> (Int, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    a, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    b) g
    g of
        (Int
    x, g
    g') -> (Int -> a
    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 = (Char, Char) -> g -> (Char, g)
    forall a g. (Enum a, RandomGen g) => (a, a) -> g -> (a, g)
    randomEnum
      random :: forall g. RandomGen g => g -> (Char, g)
    random  = g -> (Char, g)
    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 = (Bool, Bool) -> g -> (Bool, g)
    forall a g. (Enum a, RandomGen g) => (a, a) -> g -> (a, g)
    randomEnum
      random :: forall g. RandomGen g => g -> (Bool, g)
    random  = g -> (Bool, g)
    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 = (Integer, Integer) -> g -> (Integer, g)
    forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
    randomInteger
      random :: forall g. RandomGen g => g -> (Integer, g)
    random  = (Integer, Integer) -> g -> (Integer, g)
    forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger (Int
    forall a. Bounded a => a
    minBound::Int), Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger (Int
    forall a. Bounded a => a
    maxBound::Int))

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

    instance Random Word64 where
      randomR :: forall g. RandomGen g => (Word64, Word64) -> g -> (Word64, g)
    randomR = (Word64, Word64) -> g -> (Word64, g)
    forall g. RandomGen g => (Word64, Word64) -> g -> (Word64, g)
    randomWord64
      random :: forall {t}. RandomGen t => t -> (Word64, t)
    random  = g -> (Word64, g)
    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 = (Int32, Int32) -> g -> (Int32, g)
    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') = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    g in (Word32 -> Int32
    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 = (Int64, Int64) -> g -> (Int64, g)
    forall g. RandomGen g => (Int64, Int64) -> g -> (Int64, g)
    randomInt64
      random :: forall g. RandomGen g => g -> (Int64, g)
    random  = g -> (Int64, g)
    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') = (Word32, Word32) -> g -> (Word32, g)
    forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
    randomWord32 (Word8 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    l, Word8 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    h) g
    g
        in (Word32 -> Word8
    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') = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    g in (Word32 -> Word8
    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') = (Int32, Int32) -> g -> (Int32, g)
    forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
    randomInt32 (Int8 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int8
    l, Int8 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int8
    h) g
    g
        in (Int32 -> Int8
    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') = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    g in (Word32 -> Int8
    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') = (Word32, Word32) -> g -> (Word32, g)
    forall g. RandomGen g => (Word32, Word32) -> g -> (Word32, g)
    randomWord32 (Word16 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word16
    l, Word16 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word16
    h) g
    g
        in (Word32 -> Word16
    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') = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    g in (Word32 -> Word16
    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') = (Int32, Int32) -> g -> (Int32, g)
    forall g. RandomGen g => (Int32, Int32) -> g -> (Int32, g)
    randomInt32 (Int16 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int16
    l, Int16 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int16
    h) g
    g
        in (Int32 -> Int16
    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') = g -> (Word32, g)
    forall g. RandomGen g => g -> (Word32, g)
    next g
    g in (Word32 -> Int16
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    x, g
    g')