Skip to content

Instantly share code, notes, and snippets.

@VictorBezak
Last active February 8, 2020 22:14
Show Gist options
  • Save VictorBezak/dfe96dfdeab585fbc975f7fb2bf5d359 to your computer and use it in GitHub Desktop.
Save VictorBezak/dfe96dfdeab585fbc975f7fb2bf5d359 to your computer and use it in GitHub Desktop.
Elm -- Updating Nested Records
module Main exposing (main)
-- Record Schemas
type alias SecondLayer =
{ target_value : String }
type alias FirstLayer =
{ l2_value : SecondLayer }
type alias Model =
{ l1_value : FirstLayer }
-- Model Initialization
init : Model
init = {l1_value = {l2_value = {target_value = "Update Me!"} } }
{- Every record update returns a value (the new record),
and each function is only capable of returning a single value.
If we update a nested record, we are therefor also updating
all of the records that it is contained within.
For each one of the records that are getting updated (however
many layers deep you are), you must provide a separate helper
function that can process that layer and return its updated
value.
-}
updateFirstLayer : (FirstLayer -> FirstLayer) -> Model -> Model
updateFirstLayer updateFunction model =
{ model | l1_value = updateFunction model.l1_value }
updateSecondLayer : (SecondLayer -> SecondLayer) -> FirstLayer -> FirstLayer
updateSecondLayer updateFunction firstLayer =
{ firstLayer | l2_value = updateFunction firstLayer.l2_value }
setTargetValue : String -> SecondLayer -> SecondLayer
setTargetValue str secondLayer =
{ secondLayer | target_value = str }
{- Once we have created separate helper functions to process and
return each layer, then we can tie it all together in a final update
function.
This final function will:
1. accept your inital model state and your new target value as input
2. update the target value first
3. then pipe that updated layer into the next layer's update function
4. this continue's until all layers have been updated from the inside-out
5. and finally, the fully updated Model is returned as the function's single output
***
Similar to algebra with composite functions, we process the innermost
function first, and supply it's output to the encasing function.
function( function( function( x ) ) )
IS EQUIVALENT TO
updateFirstLayer( updateSecondLayer( setTargetValue( str ) ) )
-}
updateTargetValue : String -> Model -> Model
updateTargetValue str =
( updateFirstLayer <| updateSecondLayer <| setTargetValue str )
-- Now we only need to call this single function to update our nested record
update : Model
update =
model
|> updateTargetValue "Hello, World"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment