diff --git a/docs/fsharp/language-reference/copy-and-update-record-expressions.md b/docs/fsharp/language-reference/copy-and-update-record-expressions.md index ef0fca25502ca..98bd0664dabed 100644 --- a/docs/fsharp/language-reference/copy-and-update-record-expressions.md +++ b/docs/fsharp/language-reference/copy-and-update-record-expressions.md @@ -32,6 +32,32 @@ To update only two fields in that record you can use the *copy and update record [!code-fsharp[Main](~/samples/snippets/fsharp/lang-ref-1/snippet1906.fs)] +## Nested Record Copy and Update + +In F# 7.0 and later, the *copy and update expression* has been enhanced to support updates on nested record fields. This feature allows for more concise syntax when working with deeply nested records. + +Consider the following example: + +### Before + +[!code-fsharp[Main](~/samples/snippets/fsharp/lang-ref-1/snippet19061.fs)] + +### After + +With the new feature, you can use dot-notation to reach nested fields and update them directly: + +[!code-fsharp[Main](~/samples/snippets/fsharp/lang-ref-1/snippet19062.fs)] + +This syntax eliminates the need for multiple `with` expressions. Instead, it allows for specifying updates on nested fields directly, while still allowing multiple fields (even at different levels of nesting) to be updated in the same expression. + +### Anonymous Records + +The same syntax extension works for anonymous records as well. Additionally, you can use this syntax to copy and update regular records into anonymous ones, adding new fields in the process: + +[!code-fsharp[Main](~/samples/snippets/fsharp/lang-ref-1/snippet19063.fs)] + +This flexibility ensures that the same concise syntax applies whether you're working with regular or anonymous records. + ## See also - [Records](records.md) diff --git a/samples/snippets/fsharp/lang-ref-1/snippet19061.fs b/samples/snippets/fsharp/lang-ref-1/snippet19061.fs new file mode 100644 index 0000000000000..f4193b1b14cab --- /dev/null +++ b/samples/snippets/fsharp/lang-ref-1/snippet19061.fs @@ -0,0 +1,10 @@ +type SteeringWheel = { Type: string } +type CarInterior = { Steering: SteeringWheel; Seats: int } +type Car = { Interior: CarInterior; ExteriorColor: string option } + +let beforeThisFeature x = + { x with Interior = { x.Interior with + Steering = {x.Interior.Steering with Type = "yoke"} + Seats = 5 + } + } diff --git a/samples/snippets/fsharp/lang-ref-1/snippet19062.fs b/samples/snippets/fsharp/lang-ref-1/snippet19062.fs new file mode 100644 index 0000000000000..e455e68d1baec --- /dev/null +++ b/samples/snippets/fsharp/lang-ref-1/snippet19062.fs @@ -0,0 +1,2 @@ +let withTheFeature x = + { x with Interior.Steering.Type = "yoke"; Interior.Seats = 5 } diff --git a/samples/snippets/fsharp/lang-ref-1/snippet19063.fs b/samples/snippets/fsharp/lang-ref-1/snippet19063.fs new file mode 100644 index 0000000000000..e14c3257ea5a9 --- /dev/null +++ b/samples/snippets/fsharp/lang-ref-1/snippet19063.fs @@ -0,0 +1,4 @@ +let updatedRecord = + {| originalRecord with + Interior.Seats = 4; + Price = 35000 |}