If an item in a collection was clicked, we would like to randomly change its properties. Color, scale etc.
Following code shows a failed attempt:
randomUpdate: Item -> Generator Item
-- implementation omitted for brevity.
updateItem: Id -> Seed -> List Item -> (List Item, Seed)
updateItem id seed =
List.map (\ item ->
if item.id==id then
Random.step (randomUpdate item) seed -- ERROR
else
item
)
Question
What would be a simple way to implement updateItem?
Scenario 2
I write quite a bit of code that deals with random numbers. Mostly for animations, games and generative art.
I start out by hard-coding values. And later, passing model & seed along the update chain
So functions requiring randomness can use them while updating both the model & seed.
Question
How to handle these scenarios when iteratively coding a project?
Pass seed & model
Wrap update methods in generators
Or …?
FYI: For non-update scenario, I always prefer to write and combine Generators. The problem starts when I have to update existing values with them. Most of the time the update depth is 2 or 3 levels. Model → Collection → Record
About Scenario 1: if I understand correctly your issue, when you need to “carry over” something while looping you need to do a List.foldl, which in the end will produce a new list with updated (or not) items and a seed to save somewhere for the next round.
I would split the process into two steps:
click → save the cell coordinates we are modifying to the model and call generator
generator → produces message for cell update
type Msg
= GotRandomColor Colors
| Randomize
type alias Colors =
{ red : Int
, green : Int
, blue : Int
}
colorsGenerator : Random.Generator Colors
colorsGenerator =
Random.map3 Colors colorGenerator colorGenerator colorGenerator
colorGenerator : Random.Generator Int
colorGenerator =
Random.int 0 255
generateRandomColors : Cmd Msg
generateRandomColors =
Random.generate GotRandomColor colorsGenerator
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Randomize ->
-- save position here
( model, generateRandomColors )
GotRandomColor color ->
( { model | color = color }, Cmd.none )
I made something similar for a snake game (using random to spawn an apple): Snake
P.S. an updated Ellie with a grid pattern - click on any square to change the color … not the most elegant code - but the point is splitting the process into 2 steps.