{-# LANGUAGE TypeApplications #-}
module Test.ThreadNet.Util.Seed (
Seed (..)
, combineWith
, runGen
) where
import Data.Bits (xor)
import Data.Coerce (coerce)
import Test.QuickCheck
import Test.QuickCheck.Gen
import Test.QuickCheck.Random (mkQCGen)
newtype Seed = Seed Int
deriving (Seed -> Seed -> Bool
(Seed -> Seed -> Bool) -> (Seed -> Seed -> Bool) -> Eq Seed
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Seed -> Seed -> Bool
== :: Seed -> Seed -> Bool
$c/= :: Seed -> Seed -> Bool
/= :: Seed -> Seed -> Bool
Eq, Int -> Seed -> ShowS
[Seed] -> ShowS
Seed -> String
(Int -> Seed -> ShowS)
-> (Seed -> String) -> ([Seed] -> ShowS) -> Show Seed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Seed -> ShowS
showsPrec :: Int -> Seed -> ShowS
$cshow :: Seed -> String
show :: Seed -> String
$cshowList :: [Seed] -> ShowS
showList :: [Seed] -> ShowS
Show)
instance Semigroup Seed where
<> :: Seed -> Seed -> Seed
(<>) = (Int -> Int -> Int) -> Seed -> Seed -> Seed
forall a b. Coercible a b => a -> b
coerce (forall a. Bits a => a -> a -> a
xor @Int)
combineWith :: Integral a => Seed -> a -> Seed
combineWith :: forall a. Integral a => Seed -> a -> Seed
combineWith Seed
seed a
x = Seed
seed Seed -> Seed -> Seed
forall a. Semigroup a => a -> a -> a
<> Int -> Seed
Seed (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x)
runGen :: Seed -> Gen a -> a
runGen :: forall a. Seed -> Gen a -> a
runGen (Seed Int
seed) Gen a
g =
Gen a -> QCGen -> Int -> a
forall a. Gen a -> QCGen -> Int -> a
unGen Gen a
g QCGen
qcSeed Int
qcSize
where
qcSize :: Int
qcSize = Int
30 :: Int
qcSeed :: QCGen
qcSeed = Int -> QCGen
mkQCGen Int
seed
instance Arbitrary Seed where
arbitrary :: Gen Seed
arbitrary = Int -> Seed
Seed (Int -> Seed) -> Gen Int -> Gen Seed
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
forall a. Bounded a => a
minBound, Int
forall a. Bounded a => a
maxBound)