Skip to content

Instantly share code, notes, and snippets.

@dszakallas
Created February 11, 2017 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dszakallas/7ee78b910aa940a7ffc315db4c597bd7 to your computer and use it in GitHub Desktop.
Save dszakallas/7ee78b910aa940a7ffc315db4c597bd7 to your computer and use it in GitHub Desktop.
randomNumberGenerator
{-# LANGUAGE NoImplicitPrelude #-}
module Rng where
import GHC.Show (Show)
import GHC.Base (Eq, ($))
import GHC.Num ((*), (+), Integer)
import GHC.Float (Float, Double)
import GHC.Real (fromIntegral, (/))
import GHC.Enum (maxBound)
import Data.Int (Int64, Int32, Int16, Int8)
import Data.Bits ((.&.), shiftR)
-- Random number generator
newtype Rng = Rng Int64 deriving (Show, Eq)
next :: Rng -> (Int32, Rng)
next (Rng seed) = let
nextSeed = (seed * 0x5DECE66D + 0xB) .&. 0xFFFFFFFFFFFF
in (fromIntegral $ nextSeed `shiftR` 16, Rng nextSeed)
type Rand a = Rng -> (a, Rng)
unit :: a -> Rand a
unit a rng = (a, rng)
fmap :: (a -> b) -> Rand a -> Rand b
fmap f rand rng_1 = let
(a, rng_2) = rand rng_1
in (f a, rng_2)
join :: Rand (Rand a) -> Rand a
join rrand rng_1 = let
(rand, rng_2) = rrand rng_1
(a, rng_3) = rand rng_2
in (a, rng_3)
integer :: Rand Integer
integer = fmap fromIntegral next
int8 :: Rand Int8
int8 = fmap fromIntegral next
int16 :: Rand Int16
int16 = fmap fromIntegral next
int32 :: Rand Int32
int32 = next
int64 :: Rand Int64
int64 = fmap fromIntegral next
float :: Rand Float
float = fmap (\x -> fromIntegral x / fromIntegral (maxBound :: Int32)) next
double :: Rand Double
double = fmap (\x -> fromIntegral x / fromIntegral (maxBound :: Int32)) next
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment