Generics 为什么可以';我不能创建一个泛型函数吗?

Generics 为什么可以';我不能创建一个泛型函数吗?,generics,types,f#,Generics,Types,F#,在下面的代码中,编译器假定参数r的类型为Rec2。由于Rec1类型具有函数定义中使用的所有字段,因此可以使用函数注释创建r为Rec1类型的函数。到目前为止,一切顺利 但我希望r是另一种类型,比如“a”。不幸的是,我不知道a是什么。所以我尝试创建一个泛型函数,r是泛型类型。下面的代码显示编译器不允许我这样做 有没有办法创建这样一个泛型函数 type Rec1 = {A: int; B: string} let r0 = {A = 0; B = "Hello"} type Rec2 = {A: in

在下面的代码中,编译器假定参数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' *)
type Rec1={A:int;B:string}
设r0={A=0;B=“Hello”}
类型Rec2={A:int;B:string;C:float}
设f2(x,r)={A=r.A;B=r.B;C=x}
//val f2:x:float*r:Rec2->Rec2
设f1(x,(r:Rec1))={A=r.A;B=r.B;C=x}
//val f1:x:float*r:Rec1->Rec2

让g评论显示您实际上正在使用CSVProvider,这意味着您不需要这样做。您已经进行了静态键入:

使用FSharp.Data文档中的示例csv文件:

日期、打开、高、低、关闭、音量、调整关闭 2012-01-27,29.45,29.53,29.17,29.23,44187700,29.23 2012-01-26,29.61,29.70,29.40,29.50,49102800,29.50 2012-01-25,29.07,29.65,29.07,29.56,59231700,29.56 2012-01-24,29.47,29.57,29.18,29.3451703300,29.34

只需使用
Stocks.Row
作为类型:

type Stocks = CsvProvider<"test.csv">

type Rec2 = {Open: decimal; Close: decimal; Extra: string}

let openCloseWithExtra (stockRow : Stocks.Row) =
    {Open = stockRow.Open; Close = stockRow.Close; Extra = "extra"}

您试图解决什么问题?您的泛型类型不是任何类型,它应该有两个名为A和B的字段,因此您需要能够指定该限制。您可以使用静态约束以通用方式读取值,但不能以通用方式创建记录。因为简短的回答是“否”,所以泛型不是这样工作的。答案很长,是的,但你不想这么做。@Gustavo-我实际上有一个类型,有两个字段,分别命名为a和B,但我不知道它的名称。它是由Csv提供程序创建的对象中的行的类型,我无法确定其签名以便将其插入类型批注中。@索尔达尔玛:提供的类型是静态的,因此可以在类型批注中使用。这就是类型提供程序的全部要点。看看你的另一个问题的答案。好的,谢谢。但是你是怎么找到股票的?罗是那种类型的?我的意思是,有没有一个我可以遵循的过程来发现Stocks.Row就是这个类型?@Soldalma可能最明显的事情是查看
Stocks.GetSample()的类型。Rows
,你会看到它被列为
seq
,所以你知道每个元素都有类型
CsvProvider.Row
,例如,在本例中,
Stocks.Row
。我已经这样做了,但我没有弄清楚
CsvProvider
的意思是
Stocks
,CsvProvider的名称。
let inline anyOpenCloseWithExtra stockRow =
    let open' = ((^T) : (member Open : decimal) (stockRow))
    let close' = ((^T) : (member Close : decimal) (stockRow))
    {Open = open'; Close = close'; Extra = "extra"}