    module Test.Framework.Seed where

    import Test.Framework.Utilities

    import System.Random (StdGen, mkStdGen, randomIO)

    import Data.Char ( toLower )

    data Seed = FixedSeed Int
              | RandomSeed

    instance Show Seed where
        show :: Seed -> String
    show Seed
    RandomSeed    = String
    "random"
        show (FixedSeed Int
    n) = Int -> String
    forall a. Show a => a -> String
    show Int
    n

    instance Read Seed where
        readsPrec :: Int -> ReadS Seed
    readsPrec Int
    prec String
    xs = if (Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toLower String
    random_prefix String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == String
    "random"
                            then [(Seed
    RandomSeed, String
    rest)]
                            else ((Int, String) -> (Seed, String))
    -> [(Int, String)] -> [(Seed, String)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> Seed
    FixedSeed (Int -> Seed) -> (Int, String) -> (Seed, String)
    forall a c b. (a -> c) -> (a, b) -> (c, b)
    `onLeft`) (Int -> ReadS Int
    forall a. Read a => Int -> ReadS a
    readsPrec Int
    prec String
    xs)
          where (String
    random_prefix, String
    rest) = Int -> String -> (String, String)
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    6 String
    xs

    -- | Given a 'Seed', returns a new random number generator based on that seed and the
    -- actual numeric seed that was used to build that generator, so it can be recreated.
    newSeededStdGen :: Seed -> IO (StdGen, Int)
    newSeededStdGen :: Seed -> IO (StdGen, Int)
    newSeededStdGen (FixedSeed Int
    seed) = (StdGen, Int) -> IO (StdGen, Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((StdGen, Int) -> IO (StdGen, Int))
    -> (StdGen, Int) -> IO (StdGen, Int)
    forall a b. (a -> b) -> a -> b
    $ (Int -> StdGen
    mkStdGen Int
    seed, Int
    seed)
    newSeededStdGen Seed
    RandomSeed = IO (StdGen, Int)
    newStdGenWithKnownSeed

    newStdGenWithKnownSeed :: IO (StdGen, Int)
    newStdGenWithKnownSeed :: IO (StdGen, Int)
    newStdGenWithKnownSeed = do
        seed <- IO Int
    forall a (m :: * -> *). (Random a, MonadIO m) => m a
    randomIO
        return (mkStdGen seed, seed)