如何在F#中将类型作为函数参数传递?

时间:2018-06-08 17:34:56

标签: f#-fake

我的代码如下。我正在编写代码来分组,然后平均另一行,这就是我在下面的内容。但是我不是每次都传递整个函数,而是希望能够将CSV或数据作为函数参数传递到一行中,并为不同的数据集多次执行此操作。你可以从" row.income"中看到。和" .Rows"我正在使用TYPE,但是当我稍后尝试使用TYPE调用该函数时,它会给我一个错误。我该怎么做呢?

仅供参考,错误是行不存在,因为我正在使用"值"作为参数而不是实际的CSV文件,因为我稍后会调用它。这是我需要修复的错误,以便能够在将函数作为参数传递时调用函数中的特定行。

// When I try to call the function with Type

type Csvdata = CsvProvider<somefile>

state Csvdata

// This results in an error 

1 个答案:

答案 0 :(得分:3)

您不能以您描述的方式将类型作为参数传递。您可以传递泛型类型参数,但要执行您想要的操作,语法会略有不同,因为您需要在内联函数上使用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的方法返回另一个类型,^a^a是类型提供程序本身的类型,在本例中为CsvProvider<"csv.txt">,但我们只需要一个名为Rows的属性,它为我们提供某种类型的序列{{ 1}}。最后,^b表示每行的类型,在本例中为^b,但我们只需要具有Csvdata.Row属性decimal

通过以这种方式使用类型约束,您可以传递满足约束的任何类型的组合,因此它适用于任何具有Income列的CSV文件的CsvProvider。 / p>

运行示例文件的代码会提供以下输出:

Income