module Random where

import Control.Monad.State.Lazy
import Test.HUnit hiding (State)

type Random a = State Integer a

-- X <- (aX + c) mod m
fresh :: Random Integer
fresh = do
  lastRand <- get
  let newRand = (6364136223846793005 * lastRand + 1442695040888963407) `mod` 2 ^ 64
  put newRand
  return newRand

runPRNG :: Random a -> Integer -> a
runPRNG action init = fst $ runState action init

threeRandomNumbers :: Random [Integer]
threeRandomNumbers = do
  rand1 <- fresh
  rand2 <- fresh
  rand3 <- fresh
  return [rand1, rand2, rand3]

testThreeRandomNumbers :: Test
testThreeRandomNumbers = TestCase $
  let seed = 1
      randomNumbers = runPRNG threeRandomNumbers seed
    in do
      assertEqual "test1" [7806831264735756412, 9396908728118811419, 11960119808228829710] randomNumbers

-- Tests
allTests :: Test
allTests = TestList [
  TestLabel "testThreeRandomNumbers" testThreeRandomNumbers
  ]
