如何在 F# 中将类型作为函数参数传递?
How to pass a type as a function parameter in F#?
我的代码如下。我正在编写代码来分组,然后平均另一行,这就是我在下面的内容。但不是每次都传递整个函数,我希望能够在一行中将 CSV 或数据作为函数参数传递,并对不同的数据集执行多次。正如您从 "row.income" 和“.Rows”中看到的那样,我正在使用 TYPE,但是当我稍后尝试使用 TYPE 调用该函数时,它给了我一个错误。我该怎么做?
仅供参考,错误是行不存在,因为我使用 "values" 作为参数而不是实际的 CSV 文件,因为我稍后会调用它。这是我需要修复的错误,以便能够调用函数中的特定行,同时将类型作为参数传递。
// When I try to call the function with Type
type Csvdata = CsvProvider<somefile>
state Csvdata
// This results in an error
您不能按照您描述的方式将类型作为参数传递。您可以传递泛型类型参数,但要执行您想要的操作,语法会略有不同,因为您需要在内联函数上使用 Statically Resolved Type Parameters。使用具有以下数据的示例 csv.txt
:
name,income
bob,134.56
mary,350.13
实现看起来像这样:
let inline state< ^t, ^a, ^b when ^t: (static member GetSample: unit -> ^a)
and ^a: (member Rows: ^b seq)
and ^b: (member Income: decimal) > () =
let sample = (^t: (static member GetSample: unit -> ^a) ())
let rows = (^a: (member Rows: ^b seq) sample)
rows |> Seq.averageBy (fun row -> (^b: (member Income: decimal) row))
type Csvdata = CsvProvider<"csv.txt", HasHeaders = true>
state<Csvdata, CsvProvider<"csv.txt">, Csvdata.Row> ()
此处,^t
是您文件的特定类型的提供程序,在本例中为 Csvdata
,但我们只需要一个名为 GetSample
的方法,即 returns另一种,^a
。 ^a
是类型提供者本身的类型,在本例中为 CsvProvider<"csv.txt">
,但我们只需要有一个名为 Rows
的 属性,它给我们一个序列某种类型 ^b
。最后,^b
表示每一行的类型,在本例中为 Csvdata.Row
,但我们只需要有一个名为 Income
的 decimal
属性。
通过以这种方式使用类型约束,您可以传递满足约束的任何类型组合,因此它适用于任何 CsvProvider
具有 Income
列的任何 CSV 文件.
运行 我们示例文件的代码给出以下输出:
val it : decimal = 242.345M
我的代码如下。我正在编写代码来分组,然后平均另一行,这就是我在下面的内容。但不是每次都传递整个函数,我希望能够在一行中将 CSV 或数据作为函数参数传递,并对不同的数据集执行多次。正如您从 "row.income" 和“.Rows”中看到的那样,我正在使用 TYPE,但是当我稍后尝试使用 TYPE 调用该函数时,它给了我一个错误。我该怎么做?
仅供参考,错误是行不存在,因为我使用 "values" 作为参数而不是实际的 CSV 文件,因为我稍后会调用它。这是我需要修复的错误,以便能够调用函数中的特定行,同时将类型作为参数传递。
// When I try to call the function with Type
type Csvdata = CsvProvider<somefile>
state Csvdata
// This results in an error
您不能按照您描述的方式将类型作为参数传递。您可以传递泛型类型参数,但要执行您想要的操作,语法会略有不同,因为您需要在内联函数上使用 Statically Resolved Type Parameters。使用具有以下数据的示例 csv.txt
:
name,income
bob,134.56
mary,350.13
实现看起来像这样:
let inline state< ^t, ^a, ^b when ^t: (static member GetSample: unit -> ^a)
and ^a: (member Rows: ^b seq)
and ^b: (member Income: decimal) > () =
let sample = (^t: (static member GetSample: unit -> ^a) ())
let rows = (^a: (member Rows: ^b seq) sample)
rows |> Seq.averageBy (fun row -> (^b: (member Income: decimal) row))
type Csvdata = CsvProvider<"csv.txt", HasHeaders = true>
state<Csvdata, CsvProvider<"csv.txt">, Csvdata.Row> ()
此处,^t
是您文件的特定类型的提供程序,在本例中为 Csvdata
,但我们只需要一个名为 GetSample
的方法,即 returns另一种,^a
。 ^a
是类型提供者本身的类型,在本例中为 CsvProvider<"csv.txt">
,但我们只需要有一个名为 Rows
的 属性,它给我们一个序列某种类型 ^b
。最后,^b
表示每一行的类型,在本例中为 Csvdata.Row
,但我们只需要有一个名为 Income
的 decimal
属性。
通过以这种方式使用类型约束,您可以传递满足约束的任何类型组合,因此它适用于任何 CsvProvider
具有 Income
列的任何 CSV 文件.
运行 我们示例文件的代码给出以下输出:
val it : decimal = 242.345M