Bosh
Bosh

Reputation: 8738

How do I use Random generators in elm 0.17 with a user-specified seed?

In Elm 0.17, I'd like to run a program that relies on random numbers, but I'd like to have a user-specified seed. This is to have reproducible results across multiple user sessions: users who enter the same seed should see the same results.

But I can't figure out how to affect the behavior of built-in functions like:

Random.list 10 (Random.int 0 100)

With a call like the one above, I want to get the same list of 10 random numbers each time I feed in the same seed. But I can't figure out how to feed in a seed at all. I'd appreciate any help!

Upvotes: 3

Views: 614

Answers (2)

halfzebra
halfzebra

Reputation: 6797

Overview

Generating a random value with Random, using user-specified seed is possible with Random.step

You need to specify a Generator and a Seed, where Generator a is a function to produce random values of a type, using integer Seed

To create a Seed from integer, you need to use Random.initialSeed function, since Seed is not a plain integer, it's a data-structure containing meta-information for the the next steps of the Generator

Random.step

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

Calling Random.step will return a new state (a, Seed), where a is your random value, and Seed is the seed, required for generating the next random value.

Example

I have made a comprehensive example, which shows how to use generator for producing random values: Random value with user-specified seed

The example might be too big for the answer so I will highlight the most important parts:

Create a generator

generator : Int -> Generator (List Int)
generator length =
    Random.list length (Random.int 0 100)

Step through generator

The seed might be specified through user input, or you can pass it as flags upon start-up.

Random.step (generator 10) seed

Upvotes: 6

Dave Compton
Dave Compton

Reputation: 1423

The expression that you specified returns a Generator. The function that generates random values is step which takes as arguments a Generator and a Seed. A Seed can be created with the function initialSeed which takes an Int that can be specified by the user as argument.

The same argument to initialSeed will result in the same Seed as output which will result in the same List of random Int values each time. The function below illustrates this.

randomSequence : Int -> List Int
randomSequence int = 
    let gen = Random.list 10 (Random.int 0 100)
        s = initialSeed int
        (res, ns) = step gen s  
    in res

Upvotes: 4

Related Questions