Last active
February 8, 2020 22:14
-
-
Save VictorBezak/dfe96dfdeab585fbc975f7fb2bf5d359 to your computer and use it in GitHub Desktop.
Elm -- Updating Nested Records
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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