How to update nested Records?
Not best practice: Create an opaque type instead.
Problem
Solution
Alternative Solution
1
type alias Movie =
2
{ title : String
3
, rating : Int
4
}
5
6
type alias Model =
7
{ currentMovie : Movie
8
}
9
​
10
rate : Int -> Model -> Model
11
rate newRating model =
12
{ model
13
| currentMovie =
14
--{ model.currentMovie | rating = newRating }
15
Debug.todo "the line above does not compile"
16
}
Copied!
1
type alias Movie =
2
{ title : String
3
, rating : Int
4
}
5
6
type alias Model =
7
{ currentMovie : Movie
8
}
9
​
10
rate : Int -> Model -> Model
11
rate newRating ({currentMovie} as model) =
12
{ model
13
| currentMovie =
14
{currentMovie | rating = newRating }
15
}
Copied!
1
type alias Movie =
2
{ title : String
3
, rating : Int
4
}
5
6
type alias Model =
7
{ currentMovie : Movie
8
}
9
​
10
rate : Int -> Model -> Model
11
rate rating ({currentMovie} as model) =
12
model
13
|> updateMovie (addRating rating)
14
​
15
updateMovie : (Movie -> Movie) -> Model -> Model
16
updateMovie fun ({currentMovie} as model) =
17
{ model | currentMovie = fun currentMovie}
18
19
addRating : Int -> Movie -> Movie
20
addRating rating movie =
21
{ movie | rating = rating}
Copied!
This is the a better solution

Question

How can I update a nested record field?

Answer

First get the nested record, then update it:
1
let
2
currentMovie = model.currentMovie
3
in
4
{ currentMovie | rating = newRating}
Copied!
For function parameters we can use the keyword as to bind fields of a record to a variable with the same name:
1
rate newRating ({currentMovie} as model) =
2
...
Copied!

Further reading