Record is a set of key-value pairs.
greeter =
{ isMorning: True
, greeting: "Good morning!"
}
It is impossible to access a value by an non-existent key.
It is impossible to dynamically modify Record's structure.
Records only allow you to update values by constant keys.
Values can not be accessed using a dynamic key to prevent possible run-time errors:
isMorningKeyName =
"isMorning "
greeter[isMorningKeyName] -- Compiler error
greeter.isMorning -- True
The alternative syntax for accessing the value allows you to extract the value, while piping through the Record:
greeter
|> .greeting
|> (++) " Have a nice day!" -- "Good morning! Have a nice day!"
Sometimes you'd want the signature of a parameter to constrain the record types you pass into functions. Extending record types makes the idea of supertypes unnecessary. The following example shows how this concept can be implemented:
type alias Person =
{ name : String
}
type alias Animal =
{ name : String
}
peter : Person
peter =
{ name = "Peter" }
dog : Animal
dog =
{ name = "Dog" }
getName : { a | name : String } -> String
getName livingThing =
livingThing.name
bothNames : String
bothNames =
getName peter ++ " " ++ getName dog
We could even take extending records a step further and do something like:
type alias Named a = { a | name : String }
type alias Totalled a = { a | total : Int }
totallyNamed : Named ( Totalled { age : Int })
totallyNamed =
{ name = "Peter Pan"
, total = 1337
, age = 14
}
We now have ways to pass these partial types around in functions:
changeName : Named a -> String -> Named a
changeName a newName =
{ a | name = newName }
cptHook = changeName totallyNamed "Cpt. Hook" |> Debug.log "who?"
Elm has a special syntax for Record updates:
model =
{ id: 1
, score: 0
, name: "John Doe"
}
update model =
{ model
| score = model.score + 100
| name = "John Johnson"
}