Clone an instance of the class, changing only some of the properties

I was wondering if there is some sugar in F # to clone an instance of a class that changes only one or more properties.

I know that in F # this is possible with entries:

let p2 = {p1 with Y = 0.0} 
+7
clone f #
source share
2 answers

One way to model copy-and-update expressions for classes is with a copy constructor that accepts optional arguments.

 type Person(first, last, age) = new (prototype: Person, ?first, ?last, ?age) = Person(defaultArg first prototype.First, defaultArg last prototype.Last, defaultArg age prototype.Age) member val First = first member val Last = last member val Age = age let john = Person("John", "Doe", 45) let jane = Person(john, first="Jane") 

EDIT

You did not ask for it, but in many cases you make the results with the mutable class more clear code:

 type Person(first, last, age) = member val First = first with get, set member val Last = last with get, set member val Age = age with get, set member this.Clone() = this.MemberwiseClone() :?> Person let john = Person("John", "Doe", 45) let jane = john.Clone() in jane.First <- "Jane" 
+8
source share

Another option is to transfer the record to the class. Something like

 type PersonState = { FirstName : string; LastName : string; } type Person private (state : PersonState) = new (firstName, lastName) = Person({ FirstName = firstName; LastName = lastName }) member this.WithFirstName value = Person { state with FirstName = value } member this.WithLastName value = Person { state with LastName = value } member this.FirstName with get () = state.FirstName member this.LastName with get () = state.LastName 

Use as

 let JohnDoe = Person("John", "Doe") let JaneDoe = JohnDoe.WithFirstName "Jane" let JaneLastName = JaneDoe.LastName 

This approach avoids explicit cloning and variability.

+5
source share

All Articles