elm-lang/core/4.0.5

NOTE: this package moved to elm/core

NOTE: this package is not compatible with Elm 0.19.1

Random

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.

It may be helpful to read about JSON decoders because they work very similarly.

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.

Generators

type Generator a

A Generator is like a recipe for generating certain random values. So a Generator Int describes how to generate integers and a Generator String describes how to generate strings.

To actually run a generator and produce the random values, you need to use functions like generate and initialSeed.

Primitive Generators

bool : Generator Bool

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) bool
int : Int -> Int -> Generator Int

Generate 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 feasible

This function can produce values outside of the range [minInt, maxInt] but sufficient randomness is not guaranteed.

float : Float -> Float -> Generator Float

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 1

Data Structure Generators

pair : Generator a -> Generator b -> Generator ( a, b )

Create 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)
list : Int -> Generator a -> Generator (List a)

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)

Custom Generators

map : (a -> b) -> Generator a -> Generator b

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)
map2 : (a -> b -> c) -> Generator a -> Generator b -> Generator c

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 genB
(a -> b -> c -> d)
-> Generator a
-> Generator b
-> Generator c
-> Generator d

Combine 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)
(a -> b -> c -> d -> e)
-> Generator a
-> Generator b
-> Generator c
-> Generator d
-> Generator e

Combine four generators.

(a -> b -> c -> d -> e -> f)
-> Generator a
-> Generator b
-> Generator c
-> Generator d
-> Generator e
-> Generator f

Combine five generators.

andThen : Generator a -> (a -> Generator b) -> Generator b

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 Char

Generate Values

generate : (a -> msg) -> Generator a -> Cmd msg

Create a command that will generate random values.

Read more about how to use this in your programs in The Elm Architecture tutorial which has a section specifically about random values.

Generate Values Manually

step : Generator a -> Seed -> ( a, Seed )

Generate 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 step 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 step call and thread that through.

seed0 = initialSeed 31415


-- step (int 0 100) seed0 ==> (42, seed1)
-- step (int 0 100) seed1 ==> (31, seed2)
-- step (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.

-- step (int 0 100) seed0 ==> (42, seed1)
-- step (int 0 100) seed0 ==> (42, seed1)
-- step (int 0 100) seed0 ==> (42, seed1)
type Seed

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.

initialSeed : Int -> 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.

Constants

maxInt : Int

The maximum value for randomly generated 32-bit ints: 2147483647

minInt : Int

The minimum value for randomly generated 32-bit ints: -2147483648