Records
A record groups named fields together — think of it as a struct or an object, but immutable.
Give every record a type alias
Name the shape with type alias, then use the name everywhere:
type alias User =
{ name : String
, age : Int
}
Construct one with the same brace syntax:
ada : User
ada =
{ name = "Ada", age = 40 }
A tip that saves confusion: always name a record with a type alias and use the
name in signatures. Writing the raw { name : String, age : Int } shape inline in
a function signature is awkward — the alias reads better and gives errors a name
to point at.
Reading fields
Dot access, or the bare .field function:
who =
ada.name -- "Ada"
names =
List.map .name [ ada, ada ] -- [ "Ada", "Ada" ]
Updating is copying
Records are immutable. "Updating" a field produces a new record; the original is untouched:
older : User
older =
{ ada | age = 41 }
ada is still { name = "Ada", age = 40 }. older is a fresh value with every
other field copied across and age set to 41. This is the heart of functional
state: you never mutate, you derive a new value. It's exactly how you'll update
your app's model later — { model | count = model.count + 1 }.
You can update several fields at once:
{ ada | name = "Ada L.", age = 41 }