Types F#中带有语句的交叉类型记录?

Types F#中带有语句的交叉类型记录?,types,f#,record,Types,F#,Record,以下代码未编译: type Person= { 名字:string 姓氏:string } 员工类型= { 名字:string 姓氏:string 薪金:整数 } 设p:Person= { FirstName=“史蒂夫” LastName=“作业” } 设e:Employee= { p,工资=1 } 解决方法是编写一个助手,可能类似于: 让员工(p:Person):员工= { FirstName=p.FirstName LastName=p.LastName 工资=未选中。默认值 } 设e:E

以下代码未编译:

type Person=
{
名字:string
姓氏:string
}
员工类型=
{
名字:string
姓氏:string
薪金:整数
}
设p:Person=
{
FirstName=“史蒂夫”
LastName=“作业”
}
设e:Employee=
{
p,工资=1
}
解决方法是编写一个助手,可能类似于:

让员工(p:Person):员工=
{
FirstName=p.FirstName
LastName=p.LastName
工资=未选中。默认值
}
设e:Employee=
{
员工p,工资=1
}
但这有点乏味

F#提供了更好的方法吗?

这是JavaScript中的常见操作,例如:

const e={
P
工资:1,
};

作为一种静态和名义类型的语言,这在F#中是不可能的,这是有意设计的

假设您确实拥有像JS这样的特性和一个值
让e={…p;Salary=1}
。然后假设您重命名了
Person
上的一个字段。应将
e
的类型推断为什么?错误消息应该说什么?这个问题没有简单的答案,在更大的代码库中,它可能变得非常复杂,很难快速理解

最好手动写出新记录。它有点冗长,但它符合一般的F#主题,即在某些维度上更显式,因此您可以在注释类型方面不太具体(允许更多类型推断)。如果你能非常含蓄地处理这两个问题,那么这将导致复杂性的爆炸


另一个可能有帮助的选项是更改模型,将重复的字段放入单独的类型中:

type Person = 
  { FirstName : string
    LastName : string }

type Employee = 
  { Person : Person
    Salary : int }

let p = 
  { FirstName = "Steve"
    LastName = "Jobs" }

let e = { Person = p; Salary = 1 }

在F#中,对类型进行建模的方式非常重要,并且会对使用它的所有代码产生连锁反应。因此,如果你的代码看起来不太好,考虑你的类型是否可以改进。

我不认为静态类型使这不可能,类型检查器只需要意识到一个记录类型中的字段是另一个记录的超集。F#没有这样做的事实回答了我的问题。我同意sdgfsdh。这不是静态类型的问题,Typescript毕竟是静态类型的。Typescript使用结构类型,因此如果某些类型拥有其他类型的所有成员,则它们可以是其他类型的子类型。虽然F#在结构上是相等的,所以呢,有赢有输。@Asti我没有说这是不可能的,因为F#是静态类型的,只是它不适合语言的设计和使用方式。我不想谈太多细节,但您指出TypeScript具有结构化类型。F#具有标称类型,因此很难以与所有现有功能良好交互的方式在顶部添加此功能。@QuickBrownFox这是一个合理的位置。OCaml在结构上是类型化的,但我想F#名义上是为互操作而类型化的。对于记录类型,可以期待将来实现结构化类型,这将使处理匿名记录变得更容易。