'What is the minimum code required to produce random numbers in Elm?
I just want to see a random number. So here's an example straight out of the docs for the Random library. I expect Random.generate
to accept a generator and a seed and return a tuple containing a random value and a new seed, as in:
generate : Generator a -> Seed -> (a, Seed)
-- Main.elm
import Random
seed0 = Random.initialSeed 31415
randomNumber = Random.generate (Random.int 0 10) seed0
main =
-- print result of randomNumber here
The compiler errors show two type mismatches:
-- TYPE MISMATCH ---------------------------------------------------- -----------
The 2nd argument to function `generate` is causing a mismatch.
5| Random.generate (Random.int 0 10) seed0
^^^^^
Function `generate` is expecting the 2nd argument to be:
Random.Generator a
But it is:
Random.Seed
The 1st argument to function `generate` is causing a mismatch.
5| Random.generate (Random.int 0 10) seed0
^^^^^^^^^^^^^^^
Function `generate` is expecting the 1st argument to be:
a -> b
But it is:
Random.Generator Int
What am I missing here?
Solution 1:[1]
The version of the docs you refer to is Core 1.0.0, which is old. Current version of Core is 4.0.5. (docs for Random here)
The function with the signature you are looking for is now named step
:
step : Generator a -> Seed -> (a, Seed)
So your refactored code would look something like this:
import Html exposing (text)
import Random
seed0 = Random.initialSeed 31415
(randomNumber, nextSeed) = Random.step (Random.int 0 10) seed0
main =
text <| toString randomNumber
Solution 2:[2]
Here is the shortest example I can think of. Because it is giving a constant seed, it will return same boolean.
If you need random number get produced at runtime, then you
have to use Random.generate
which produces Cmd
so that elm runtime can get the randomness.
In this case, some form of Platform.Program
is needed because it is the only way to run Cmd
.
import Html exposing (text)
import Random exposing (..)
main =
text <| toString <| Tuple.first <| step bool (initialSeed 1)
Solution 3:[3]
Elm 2022 (v0.19) answer:
Here's an absolute minimal example for generating a number between 0 and 1000 in Elm 0.19.1, and a runnable Ellie, which depends on elm/random. You wouldn't usually have all the ()
littered throughout, and instead you'd have Msg
and Model
, but in the interest of minimizing code:
module Main exposing (main)
import Browser
import Html
import Random
view : () -> Html.Html ()
view model =
let
-- this generates the rng number
generator =
Random.int 0 1000
-- used to seed the generator
seed =
Random.initialSeed 12345
-- Random.step returns the generated value, and a new seed.
-- Usually you store the newSeed on your model so you don't always generate the same value
( value, newSeed ) =
Random.step
generator
seed
in
Html.text <| String.fromInt value
main : Program () () ()
main =
Browser.sandbox
{ init = ()
, view = view
, update = \msg model -> model
}
Other best practices include storing some global seed on the model:
type alias Model = { globalSeed : Random.Seed }
and then using it and updating the one on the model after:
update : Msg -> Model -> (Model, Cmd.none)
update msg model =
case msg of
GenerateValue ->
let
(newValue, newSeed) =
Random.step (Random.int 0 1000) model.globalSeed
_ =
Debug.log "generated a new value" newValue
in
( {model | globalSeed = newSeed}, Cmd.none)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | wintvelt |
Solution 2 | rofrol |
Solution 3 |