An anonymous record groups named fields into an F# value without a prior named type declaration. Define it inline with {| ... |}; the compiler infers its structural type from the fields, and fields remain accessible with dot notation. section 5.4
Define and extend one inline
let company = {| Name = "My Company Inc." Town = "The Town" Country = "UK" TaxNumber = 123456 |} let companyWithBankDetails = {| company with AccountNumber = 123 SortCode = 456 |} Copy-and-update can therefore change existing data and add fields at the same time. section 5.4.1
Choose an anonymous record when named fields matter but a formal record type would add unnecessary ceremony:
- Prototype a domain shape in exploration or scripts, then promote it to a full record if the shape becomes durable. section 5.4.1
- Replace a tuple when positional fields are too opaque but defining a named record feels excessive. section 5.5
- Nest a one-off structure inside a full record, or map domain data into a JSON-shaped value for serialization. section 10.2.3
Create JSON output without a raw type
let createReport (guitars:Guitar list) = guitars |> List.countBy (fun guitar -> guitar.Brand) |> List.map (fun ((Brand brand), count) -> {| Brand = brand; Guitars = count |}) |> JsonSerializer.Serialize The anonymous record mirrors the required JSON and avoids defining a type used only for output. section 10.2.3
Anonymous records are less suitable as function inputs: inference does not work there, attributes cannot be applied, and pattern matching is unsupported. For repeated or public models, use a full record instead. section 5.4.1 section 5.5
