Here are some real world examples of record updates that could be 
streamlined at the language level, including attempts to simplify UI code 
defining record updates.

-- Update.elm
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Update updater ->
            ( updater model, Cmd.none )
        SaveFamily family ->
            ( model, Cmd.saveFamily family )
        _ ->
            ( model, Cmd.none )

-- View.elm
selected_family : Model -> UI.Node Msg
selected_family model =
    UI.form
        [ UI.class "fluid"
        , UI.onSubmit <| SaveFamily model.family
        ]
        [ UI.input
            [ UI.label "Name"
            , UI.value model.family.name
            , UI.onInput <| \val -> Update <| familyUpdater (\family -> { 
family | name = val })
            ]
        ]

familyUpdater : (Family -> Family) -> Model -> Model
familyUpdater updater model =
    { model | family = updater model.family }

-- familyUpdater looks simple enough, but at production scale with multiple 
embedded records, a few of these functions must be chained together to 
complete what could be a simple update such as 
model.family.contact.address.street = "Main Street"
-- Multiple specific Msg types such as UpdateFamily can be created to 
"clean" the view, but then it becomes really hard to achieve separation of 
concern as the Update function grows with out-of-context logic. Those 
updater functions are then moved to the Update file or you have to use many 
layers of let bindings. There are two concerns here, the update behavior 
being defined in the context of the form or becoming overly complex due to 
embedded records. The latter is more important.
-- Here's an example from another real world app :

    RcvGeocode geocode ->
        let
            address =
                extractAddress geocode

            updated =
                address |> updateAddress |> updateContact |> updateProfile 
|> updateUser model
        in
            ( { updated | geocode = geocode }, Cmd.none )

-- This would look much nicer in my opinion :

    RcvGeocode geocode ->
        ( { model | user.profile.contact.address = extractAddress geocode 
}, Cmd.none )

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to