【发布时间】:2017-03-04 20:22:22
【问题描述】:
在下面的代码中,编译器假定参数 r 是 Rec2 类型。由于类型 Rec1 具有函数定义中使用的所有字段,因此可以使用函数注释创建一个函数,其中 r 是 Rec1 类型。到目前为止,一切顺利。
但我希望 r 是另一种类型,比如 'a.不幸的是,我不知道 'a 是什么。所以我尝试创建一个泛型函数,其中 r 是泛型类型。下面的代码显示编译器不允许我这样做。
有没有办法创建这样一个通用函数?
type Rec1 = {A: int; B: string}
let r0 = {A = 0; B = "Hello"}
type Rec2 = {A: int; B: string; C: float}
let f2 (x, r) = {A = r.A; B = r.B; C = x}
// val f2 : x:float * r:Rec2 -> Rec2
let f1 (x, (r: Rec1)) = {A = r.A; B = r.B; C = x}
// val f1 : x:float * r:Rec1 -> Rec2
let g<'T> (x, (r: 'T)) = {A = r.A; B = r.B; C = x}
(* error FS0193: Type constraint mismatch. The type
'T
is not compatible with type
Rec2
The type ''T' does not match the type 'Rec2' *)
【问题讨论】:
-
你想解决什么问题?
-
您的泛型类型不是任何类型,它应该有两个名为 A 和 B 的字段,因此您需要能够指定该限制。您可以使用静态约束以通用方式读取值,但不能以通用方式创建记录。
-
因为简短的回答是否定的,这不是泛型的工作方式。很长的答案是肯定的,但你不想这样做。
-
@Gustavo - 我实际上有一个类型,其中包含两个名为 A 和 B 的字段,但我不知道它的名称。它是由 Csv 提供者创建的对象中的行的类型,我无法确定其签名以便将其插入类型注释中。
-
@Soldalma:提供的类型是静态的,因此它们可用于类型注释。这就是类型提供者的全部意义所在。查看您其他问题的答案。