F# 克隆一个类实例,只更改几个属性

F# 克隆一个类实例,只更改几个属性,f#,clone,F#,Clone,我想知道在F#中是否有一些糖分可以用来克隆一个只改变一个或几个属性的类实例 我知道在F#中,有记录是可能的: let p2 = {p1 with Y = 0.0} 模拟类的复制和更新表达式的一种方法是使用复制构造函数获取可选参数 type Person(first, last, age) = new (prototype: Person, ?first, ?last, ?age) = Person(defaultArg first prototype.First,

我想知道在F#中是否有一些糖分可以用来克隆一个只改变一个或几个属性的类实例

我知道在F#中,有记录是可能的:

let p2 = {p1 with Y = 0.0}

模拟类的复制和更新表达式的一种方法是使用复制构造函数获取可选参数

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")
编辑

您没有要求这样做,但在许多情况下,使类可变会导致更清晰的代码:

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"
输入人物(第一个、最后一个、年龄)=
成员val First=带get、set的第一个
成员val Last=带get、set的Last
成员val Age=带有get、set的年龄
成员this.Clone()=this.MemberwiseClone():?>个人
让约翰=人(“约翰”,“多伊”,45)

让jane=john.Clone()在jane.First中,另一个选项是将记录包装到类中。比如

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
用作

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

这种方法避免了显式的克隆和易变性。

为了保持代码整洁和功能有序,我决定使用OO。@GuyCoder:“对类型固有的操作使用属性和方法。之所以称之为函数式编程,是因为一些有函数式编程背景的人避免一起使用面向对象编程,他们更喜欢包含一组函数的模块,这些函数定义了与类型相关的内在函数(例如,length foo而不是foo.length)。[…]一般来说,在F#中,首选使用面向对象编程作为软件工程设备……”()好主意。不过,我很惊讶没有一个惯用的表达式来实现这一点。我认为公平地说,F#的OO方面或多或少是从主流.NET语言中复制过来的。尽管有一些添加,主要是为了支持更具功能性的样式,如对象表达式和默认的不可变性。但是总体而言,NET上的OO故事在F#中基本保持不变。Scala中引入了AFAIK Copy和update表达式,以鼓励使用具有不可变属性的类。Copy和update鼓励创建新实例,即使只更新了一个属性,也不必在create FREACH CREACH结构中声明所有内容或者。沿着这条思路,我希望F#能够有一个自动复制和更新表达式。无论如何,你的解决方案很好。我接受了它,再次感谢你的帮助。不客气。在我看来,类的复制和更新在F#中并没有明显的好处。已经有记录支持这一点。如果你打算更改属性s通常你可以定义一个
Clone
方法并使其可变。我在回答中添加了一个示例,以便你可以比较这两种方法。@Daniel我真的认为类的复制和更新将提供巨大的好处。它将使与WSDL和其他服务的互操作变得非常简单,并使F#成为“go to”语言“用于数据互操作。我甚至认为我们应该更进一步,使用操作符创建一个模式匹配复制功能,以映射到某些属性名称。非结构化或矛盾数据类型转换中的类型安全。