Immutable updates
{ value with ... } replaces selected fields and keeps the original type. The source record is unchanged.
type Digest = [
| :daily
| :weekly
]
type Profile = {
display_name: String;
}
type EmailSettings = {
digest: Digest;
}
type Settings = {
email: EmailSettings;
}
type User = {
id: Int;
name: String;
profile: Profile;
settings: Settings;
}
let renamerename: fn(user: Book.Records.UpdatingRecords.User, name: String) -> Book.Records.UpdatingRecords.User = (useruser: Book.Records.UpdatingRecords.User, namename: String) =>
{ useruser: Book.Records.UpdatingRecords.User with name = namename: String; };
Record Updates
let adaada: Book.Records.UpdatingRecords.User = User {
id = 11: Int;
name = "Ada""Ada": String;
profile = Profile { display_name = "ada""ada": String; };
settings = Settings { email = EmailSettings { digest = :daily; }; };
};
expect ✓adaada: Book.Records.UpdatingRecords.User == User {
id = 11: Int;
name = "Ada""Ada": String;
profile = Profile { display_name = "ada""ada": String; };
settings = Settings { email = EmailSettings { digest = :daily; }; };
};
✓renamerename: fn(user: Book.Records.UpdatingRecords.User, name: String) -> Book.Records.UpdatingRecords.User: fn(User, String) -> User;
let gracegrace: Book.Records.UpdatingRecords.User = renamerename: fn(user: Book.Records.UpdatingRecords.User, name: String) -> Book.Records.UpdatingRecords.User(adaada: Book.Records.UpdatingRecords.User, "Grace""Grace": String);
expect ✓gracegrace: Book.Records.UpdatingRecords.User == User {
id = 11: Int;
name = "Grace""Grace": String;
profile = Profile { display_name = "ada""ada": String; };
settings = Settings { email = EmailSettings { digest = :daily; }; };
};
//! Dotted paths update nested stored fields. Expanded entries sit one level
//! beneath `value with`.
let personalizedpersonalized: Book.Records.UpdatingRecords.User = {
adaada: Book.Records.UpdatingRecords.User with
profile.display_name = "teej""teej": String;
settings.email.digest = :weekly;
};
expect ✓personalizedpersonalized: Book.Records.UpdatingRecords.User == User {
id = 11: Int;
name = "Ada""Ada": String;
profile = Profile { display_name = "teej""teej": String; };
settings = Settings { email = EmailSettings { digest = :weekly; }; };
};Dotted paths update nested stored fields. Expanded entries sit one level beneath value with.
Mutable fields
Mark a field mut to assign it with :=. Other fields stay immutable. := yields the right-hand side, so bump returns Int. Locals, shadowing, and more assignment forms are in mutability.
type Counter = {
mut value: Int;
label: String;
}
let bumpbump: fn(counter: Book.Records.UpdatingRecords.Counter) -> Int = (countercounter: Book.Records.UpdatingRecords.Counter) => counter.value := countercounter: Book.Records.UpdatingRecords.Counter.valuevalue: Int + 11: Int;
Mutable Fields
✓bumpbump: fn(counter: Book.Records.UpdatingRecords.Counter) -> Int: fn(Counter) -> Int;
let countercounter: Book.Records.UpdatingRecords.Counter = Counter { value = 00: Int; label = "hits""hits": String; };
expect ✓bumpbump: fn(counter: Book.Records.UpdatingRecords.Counter) -> Int(countercounter: Book.Records.UpdatingRecords.Counter) == 11: Int;
expect ✓countercounter: Book.Records.UpdatingRecords.Counter == Counter { value = 11: Int; label = "hits""hits": String; };