Adrian
Adrian

Reputation: 1036

How can I randomly generate a pair of floats in Elm?

I am trying to create a Random.Generator (Float, Float) where the first Float is in some range say 0.0 1000.0 and the second between 0.0 and the first value.

Example of valid values: (12.0, 5.0) Invalid: (303.0, 800.0)

I looked over code in Random.Extra module but I wasn't able to find my way around.

The example bellow don't even compile. :)

tuple = 
  let range = float 0.0 500.0
  in flatMap (\max -> (max, float 0.0 max)) range

Upvotes: 1

Views: 398

Answers (2)

pdamoc
pdamoc

Reputation: 2923

You need to use Random.andThen

Here is a full working example (you can copy&paste it in http://elm-lang.org/try)

import Html exposing (..)
import Html.App as App

import Random exposing (Generator, generate, float, map, andThen) 
import Time exposing (every, second) 

myPair : Float -> Float -> Generator (Float, Float) 
myPair min max =
  let 
    range = float min max 
  in 
    range 
    `andThen` (\f -> map ((,) f) (float min f)) 


type Msg = Request | Update (Float, Float) 

update msg model = 
  case msg of 
    Request -> model ! [generate Update (myPair 0 1000)]
    Update pair -> pair ! []


view model = text (toString model) 


main =
  App.program 
    { init = (0,0) ! []
    , update = update 
    , view = view 
    , subscriptions = (\_ -> every (2*second) (always Request))
    }

Upvotes: 4

Andrey Kuzmin
Andrey Kuzmin

Reputation: 4479

Here is the generator code:

floatTuple : Random.Generator (Float, Float)
floatTuple =
    Random.float 0.0 1000.0 
    `Random.andThen`
    (\val1 -> Random.map ((,) val1) (Random.float 0 val1))

And here is how you can use it (in 0.17):

(tuple, nextSeed) = Random.step floatTuple initialSeed

Upvotes: 4

Related Questions