This library helps you generate pseudo-random values.
This library is all about building generators for whatever
type of values you need. There are a bunch of primitive generators like
bool and int that you can build up into fancier
generators with functions like list and map.
You use a Generator by running the generate function. If you
need random values across many frames, you will probably want to store the
most recent seed in your application state.
Note: This is an implementation of the Portable Combined Generator of L'Ecuyer for 32-bit computers. It is almost a direct translation from the System.Random module. It has a period of roughly 2.30584e18.
Create a generator that produces boolean values. The following example simulates a coin flip that may land heads or tails.
type Flip = Heads | Tails
coinFlip : Generator Flip
coinFlip =
map (\b -> if b then Heads else Tails) boolGenerate 32-bit integers in a given range.
int 0 10 -- an integer between zero and ten
int -5 5 -- an integer between -5 and 5
int minInt maxInt -- an integer in the widest range feasibleThis function can produce values outside of the range [minInt,
maxInt] but sufficient randomness is not guaranteed.
Generate floats in a given range. The following example is a generator that produces decimals between 0 and 1.
probability : Generator Float
probability =
float 0 1Create a pair of random values. A common use of this might be to generate a point in a certain 2D space. Imagine we have a collage that is 400 pixels wide and 200 pixels tall.
randomPoint : Generator (Int,Int)
randomPoint =
pair (int -200 200) (int -100 100)Create a list of random values.
floatList : Generator (List Float)
floatList =
list 10 (float 0 1)
intList : Generator (List Int)
intList =
list 5 (int 0 100)
intPairs : Generator (List (Int, Int))
intPairs =
list 10 <| pair (int 0 100) (int 0 100)Transform the values produced by a generator. The following examples show how to generate booleans and letters based on a basic integer generator.
bool : Generator Bool
bool =
map ((==) 1) (int 0 1)
lowercaseLetter : Generator Char
lowercaseLetter =
map (\n -> Char.fromCode (n + 97)) (int 0 25)
uppercaseLetter : Generator Char
uppercaseLetter =
map (\n -> Char.fromCode (n + 65)) (int 0 25)Combine two generators.
This function is used to define things like pair where you want to
put two generators together.
pair : Generator a -> Generator b -> Generator (a,b)
pair genA genB =
map2 (,) genA genBCombine three generators. This could be used to produce random colors.
import Color
rgb : Generator Color.Color
rgb =
map3 Color.rgb (int 0 255) (int 0 255) (int 0 255)
hsl : Generator Color.Color
hsl =
map3 Color.hsl (map degrees (int 0 360)) (float 0 1) (float 0 1)Combine four generators.
Combine five generators.
Chain random operations, threading through the seed. In the following example, we will generate a random letter by putting together uppercase and lowercase letters.
letter : Generator Char
letter =
bool `andThen` \b ->
if b then uppercaseLetter else lowercaseLetter
-- bool : Generator Bool
-- uppercaseLetter : Generator Char
-- lowercaseLetter : Generator CharGenerate a random value as specified by a given Generator.
In the following example, we are trying to generate a number between 0 and 100
with the int 0 100 generator. Each time we call generate we need to provide
a seed. This will produce a random number and a new seed to use if we want to
run other generators later.
So here it is done right, where we get a new seed from each generate call and
thread that through.
seed0 = initialSeed 31415
-- generate (int 0 100) seed0 ==> (42, seed1)
-- generate (int 0 100) seed1 ==> (31, seed2)
-- generate (int 0 100) seed2 ==> (99, seed3)Notice that we use different seeds on each line. This is important! If you use the same seed, you get the same results.
-- generate (int 0 100) seed0 ==> (42, seed1)
-- generate (int 0 100) seed0 ==> (42, seed1)
-- generate (int 0 100) seed0 ==> (42, seed1)A Seed is the source of randomness in this whole system. Whenever
you want to use a generator, you need to pair it with a seed.
Create a “seed” of randomness which makes it possible to generate random values. If you use the same seed many times, it will result in the same thing every time! A good way to get an unexpected seed is to use the current time.
The maximum value for randomly generated 32-bit ints.
The minimum value for randomly generated 32-bit ints.
A
Generatoris like a recipe for generating certain random values. So aGenerator Intdescribes how to generate integers and aGenerator Stringdescribes how to generate strings.To actually run a generator and produce the random values, you need to use functions like
generateandinitialSeed.