2017-03-23 75 views
3

我需要修改并为我的F Sharp记录添加新属性。但是之后它会为没有这个新字段的前一个实例提供错误。我把它作为可空,但仍是同样的错误occures,请帮我解决这个Fsharp记录中的可选参数

+1

这个问题是模糊的回答,但我怀疑答案是'with'关键字 –

+0

你可以添加一些代码到Q? –

+1

更新以前的实例,以便他们使用新的字段? –

回答

7

我想你的意思是“可选”,如“一个领域,实例化记录时,我不提供”。但是,不幸的是F#记录中没有可选字段(或幸运的是,取决于您的观点)。您指定的所有记录字段必须在您实例化时出现在处。

this closely related question见。

您可以考虑这种折衷:

  • 使用记录。每次更新记录时,F#编译器都会尖叫并提醒您有关使用此记录的所有位置,现在需要提供附加信息。附加信息可以是None作为您添加的字段(如果它们是选项)。最大的好处是:你的代码本身不需要处理所有可能的很多情况:“如果缺少field1,该怎么办?如果field2缺失,该怎么办?”

  • 使用类。当你更新这个类时,F#编译器不会对你放入类的信息执行任何完整性检查。 (您可以将记录视为所有字段都是构造函数参数的类,并且必须提供所有字段)。因此,更新类定义不会导致开销,但是您的代码需要处理所有缺少的值。

我个人比较喜欢的记录,只是因为它力量我想通过添加一个新的领域的影响。

当然有一个中间地带:您可以使用记录,但通过静态成员什么都实例化所有的人:

type Name = 
    { 
     First: string 
     Family: string 
    }   
    static member Create(first, family) = { First = first; Family = family} 

如果在你的代码,你总是使用Name.Create实例记录,您当然可以添加一个MiddleName字段,而不需要任何消费者代码注意。

5

Option type优于F#中无效,原因很简单,即“未初始化变量”不思考的功能性的方式存在。通过构建一个表示VacationRequest这必须由上司批准的记录,

让我们开始。

type VacationRequest = 
    {Name : string 
    Date : DateTime 
    Approval : string option} 

与方法的问题是,所有的字段都必须在建设分配,所以这不会编译:

let holiday = 
    {Name = "Funk" 
    Date = DateTime(2020,12,31)} 

您可以解决此使用的辅助功能,它隐集选项值。

let fillInRequest name date = 
    {Name = name 
    Date = date 
    Approval = None} 

现在您可以使用帮助函数来构建记录。

let holiday = fillInRequest "Funk" <| DateTime(2020,12,31) 

将代码发送给FSI时通知有趣的事情。

val holiday : VacationRequest = {Name = "Funk"; 
           Date = 31/12/2020 12:00:00 ; 
           Approval = null;} 

然后老板可以更新请求(创建一个新记录

let approvedHoliday = 
    {holiday with Approval = Some "boss' name"} 
val approvedHoliday : VacationRequest = {Name = "Funk"; 
             Date = 31/12/2020 12:00:00 ; 
             Approval = Some "boss' name";} 

或将其发回不变

let betterLuckNextTime = holiday