Skip to content

Instantly share code, notes, and snippets.

@r00k
Last active April 2, 2024 20:17
Show Gist options
  • Save r00k/71433db62959449762e26976261be9b7 to your computer and use it in GitHub Desktop.
Save r00k/71433db62959449762e26976261be9b7 to your computer and use it in GitHub Desktop.
-- I've successfully written a random generator for Circles.
randomCircle : Random.Generator Circle
randomCircle =
Random.map4
Circle
(Random.pair (Random.float -200 200) (Random.float -200 200))
(Random.float minimumRadiusLength maximumRadiusLength)
randomColor
(Random.float 0 maximumAlpha)
-- But now, I want a function that takes a Circle and either
-- returns that Circle or generates a random one.
sometimesRandomCircle : Circle -> Random.Generator Circle
sometimesRandomCircle circle =
-- This approach doesn't work. What might?
if Random.bool == True then
circle
else
randomCircle
-- I understand how to create a *fully* random Circle (or List of random Circles).
-- I want to return a random Circle half the time, and return the existing Circle the other half.
@jmitchell
Copy link

This got me thinking a Hoogle for Elm would have helped. Happy to see there is one, and it even finds Random.Extra.flattenList when I query for List (Random.Generator a) -> Random.Generator (List a).

@r00k
Copy link
Author

r00k commented Oct 29, 2016

@jmitchell - Nice find! That would indeed have helped.

@mgold
Copy link

mgold commented Oct 29, 2016

Here's how I'd do it:

andThen = flip Random.andThen

swapSome : List Circle -> Random.Generator (List Circle)
swapSome circles =
  let
    doSwap oldCircle bool =
      if bool then
        Random.Extra.constant oldCircle
      else
        randomCircle
  in
    Random.list (List.length circles) Random.bool -- or use a non-uniform generator of booleans
    |> andThen (\bools -> List.map2 doSwap circles bools |> Random.Extra.flattenList)

Tricky little problem though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment