Records
When two record types share field names, the last defined wins unless you annotate:
11.1 Defining and creating
type person = {
name : string;
age : int;
email : string option;
}
let alice = { name = "Alice"; age = 30; email = None }11.2 Accessing fields
alice.name (* "Alice" *)
let { name; age; _ } = alice (* destructuring with field punning *)
let greet { name; _ } = "Hi " ^ name11.3 Functional update (copy with changes)
let older = { alice with age = alice.age + 1 } (* alice is unchanged *)11.4 Field punning when constructing
let make name age = { name; age; email = None }11.5 Type-directed disambiguation
When two record types share field names, the last defined wins unless you annotate:
type a = { id : int }
type b = { id : int; label : string }
let get_id (x : a) = x.id
let v = ({ id = 1 } : a)
let w = M.{ id = 1 } (* or qualify with a module path: { M.id = 1 } *)11.6 Mutable fields
type counter = { mutable count : int }
let c = { count = 0 }
let () = c.count <- c.count + 111.7 Parameterised records
type 'a box = { value : 'a; label : string }
let b = { value = 42; label = "answer" } (* int box *)