I am using the "compose" pattern in Elm.
In Main.elm
, I am generating an initial seed for Random
using the following:
type alias Model =
{ ...
, seed : Seed
}
initialModel : Model
initialModel =
{ ...
, seed = initialSeed 0
}
init : ( Model, Cmd Msg )
init =
( initialModel, generate InitializeSeed (int minInt maxInt) )
type Msg
= ...
| InitializeSeed Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
...
InitializeSeed value ->
( { model | seed = Random.initialSeed value }, Cmd.none )
which seems to work well for initializing the random number generator seed to a random starting value.
I have an "independent" widget that is used in the main application. I would like to pass the seed down to that widget on receipt of the InitializeSeed
message and then retrieve the value as it changes in the child widget (using Random.step
) so that I can then update other widgets' seeds as they need the generator.
How can I generate a message for the child widget from the update
function in Main
so that I can pass the seed down to the child? How can the child return the updated seed back to the parent?
UPDATE:
I figured out how to pass the seed down to the child widget, although I am not certain that this is best way.
The child code looks like this:
type alias Model =
{ ...
, seed : Seed
}
replaceSeed : Model -> Seed -> Model
replaceSeed model seed =
{ model | seed = seed }
and in the parent, I modified the update
function like this:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
...
InitializeSeed value ->
let
seed =
Random.initialSeed value
child_ =
Child.replaceSeed model.child seed
in
( { model
| seed = seed
, child = child_
}
, Cmd.none
)
I am still looking for a way to have the child return the updated seed.
While the top level update function in any Elm program must be
update : Msg -> Model -> (Model, Cmd Msg)
there are no limitations on the shape of any of its descendents. So nothing prevents you defining for your child
update : Seed -> Msg -> Model -> (Model, Cmd Msg, Seed)
or, if the child never returns any commands
update : Seed -> Msg -> Model -> (Model, Seed)
Maybe you have several things to pass down, including for example a parent message. Then you could go as far as
type alias Config msg =
{ seed : Seed
, someParentMessage : String -> msg
}
update : Config msg -> Msg -> Model -> (Model, Maybe (Cmd msg), Seed)
You need to wire these all up appropriately in Main of course, but the compiler will help with that.