# F# Random

last modified September 14, 2022

In this article we show how to generate random values in F#. In .NET, the built-in Random class is used to generate random values.

`Random`

represents a pseudo-random number generator, which is an
algorithm that produces a sequence of numbers that meet certain requirements for
randomness.

## Random number generator

Random number generator (RNG) produces a set of values that do not display any distinguishable patterns in their appearance.

We have two categories of random number generators: hardware random-number generators and pseudo-random number generators. Hardware random-number generators are believed to produce genuine random numbers. Pseudo-random number generators generate values based on software algorithms; they produce values that look random. But these values are deterministic and can be reproduced, if the algorithm is known.

Random generators are used in cryptography, gambling, gaming & simulations.

**Note:**For optimal security, cryptographically secure pseudo-random number generators must be used.

To improve the pseudo random-number generators, operating systems use environmental noise collected from device drivers, user input latency, or jitter from one or more hardware components. This is the core of the cryptographically secure pseudo-random number generators.

## The seed

The seed is a value which initializes the random number generator. Random number generators produce values by performing some operation on a previously generated value. When the algorithm starts, the seed is the initial value on which the generator operates. The crutial part of the generators is to provide a seed that is close to a truly random number.

let rnd = Random()

The constructor creates a random number generator with a default seed.

**Note:**Since 2016, in .NET Core the default seed has been changed from Environment.TickCount to Guid.NewGuid().GetHashCode(). It is safe to create several random instances in a loop.

## F# Random Next

The `Next`

function returns a random integer. We can specify the
lower and upper limits for the random numbers.

open System let rnd = new Random() for _ in 1..20 do let r = rnd.Next(1, 100) printf "%d " r printfn ""

In the program, we produce 20 random integers.

open System

The `Random`

class resides in the `System`

namespace.

let r = rnd.Next(1, 100)

The lower bound is inclusive, the upper bound is exclusive.

λ dotnet fsi main.fsx 29 41 92 36 10 4 41 18 17 62 9 60 58 69 11 4 44 12 31 98

## F# pick random element

In the following example, we pick a random element from a list.

open System let words = ["sky"; "cup"; "tall"; "falcon"; "cloud"] let rnd = Random() let re = words |> List.item (rnd.Next(words.Length)) printfn "%s" re

In the program, we pick a random string from a list of words.

let re = words |> List.item (rnd.Next(words.Length))

We pass a random index to the `List.item`

function. The upper bound
of the `Next`

function is the list size.

λ dotnet fsi main.fsx cloud

The next example selects a few random values.

open System let rnd = new Random() let vals = [ 1..100 ] let idx = [ for _ in 1..7 -> rnd.Next(0, 100) ] let res = idx |> List.map (fun e -> (List.item e vals)) printfn "%A" res

We select seven values randomly from a list of integers.

let vals = [ 1..100 ]

Using the range operator, we create a list of integers from 1 to 100.

let idx = [ for _ in 1..7 -> rnd.Next(0, 100) ]

In the second step, we generate seven random indexes.

let res = idx |> List.map (fun e -> (List.item e vals))

With `List.map`

and `List.item`

, we select the seven
values from the `vals`

list using the generated random indexes.

λ dotnet fsi main.fsx [84; 11; 68; 29; 87; 34; 61]

## F# generate a list of random values

In the next example, we create a new list of random values.

open System let rnd = Random() let rndVals = [ for i in 0..100 do rnd.Next(1, 101) ] printfn "%A" rndVals

A list of one hundred random integers from 1 to 100 is created.

let rndVals = [ for i in 0..100 do rnd.Next(1, 101) ]

The list is created with a F# list comprehension.

λ dotnet fsi main.fsx [79; 7; 33; 66; 85; 44; 31; 97; 3; 43; 93; 53; 45; 68; 83; 46; 59; 58; 17; 63; 80; 94; 98; 11; 65; 82; 41; 49; 100; 58; 54; 88; 53; 88; 50; 8; 55; 11; 21; 42; 20; 17; 41; 51; 98; 90; 32; 51; 60; 15; 65; 94; 78; 32; 49; 5; 28; 38; 39; 12; 43; 45; 5; 34; 67; 34; 96; 53; 86; 83; 75; 81; 88; 55; 25; 87; 47; 74; 54; 11; 93; 31; 97; 49; 32; 31; 29; 95; 87; 78; 44; 31; 33; 66; 38; 74; 50; 1; 9; 51; ...]

In the next example, we create a list of random choices.

open System type Choice = | A | B | C let getVal () = match Random().Next(1, 4) with | 1 -> A | 2 -> B | _ -> C let chx = [ for _ in 1..7 -> getVal () ] printfn "%A" chx

The program generates a list of randomly selected custom types.

type Choice = | A | B | C

With a discriminated union, we define a custom `Choice`

type. We want
a random list of these types.

let getVal () = match Random().Next(1, 4) with | 1 -> A | 2 -> B | _ -> C

We define a function that uses a match expresssion and the `Next`

function to get a new random Choice value.

let chx = [ for _ in 1..7 -> getVal () ]

The `getVal`

functio is called in the list comprehension to build a
new random list of choicese

λ dotnet fsi main.fsx [B; C; C; C; C; C; A]

## F# random endless sequence

The following example picks some random values from an endless random sequence.

open System let rnd = Random() let randomVals = seq { while true do yield rnd.Next(100) } let firstTenRandom = randomVals |> Seq.truncate 10 |> Seq.sort |> Seq.toList printfn "%A" firstTenRandom

We define an endless sequence of random integers between 1 and 100. From this sequence, we pick ten values.

let randomVals = seq { while true do yield rnd.Next(100) }

The `while`

loop is used to create an endless sequence. The
`yield`

returns a new item for each cycle.

let firstTenRandom = randomVals |> Seq.truncate 10 |> Seq.sort |> Seq.toList

With `Seq.truncate`

, we get ten values from the sequence. We sort the
values with `Seq.sort`

and transform into list with
`Seq.toList`

.

λ dotnet fsi main.fsx [15; 51; 52; 61; 77; 77; 78; 81; 87; 90]

In this article we have generated random values in F# language.