如何在F#中将类型作为函数参数传递? [英] How to pass a type as a function parameter in F#?

查看:79
本文介绍了如何在F#中将类型作为函数参数传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码如下.我正在编写代码进行分组,然后平均另一行,这是我下面的内容.但是,我希望能够只将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 

解决方案

您不能按照描述的方式将类型作为参数传递.您可以传递通用类型参数,但是要执行所需的操作,语法会有所不同,因为您需要使用

在这里,^t是文件的提供程序的特定类型,在本例中为Csvdata,但是我们只需要一个名为GetSample的方法即可返回另一种类型^a. ^a是类型提供程序本身的类型,在这种情况下为CsvProvider<"csv.txt">,但是我们只需要具有一个名为Rows的属性即可为我们提供某些类型为^b的序列.最后,^b表示每一行的类型,在本例中为Csvdata.Row,但是我们只需要具有称为Incomedecimal属性.

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

运行示例文件的代码将得到以下输出:

val it : decimal = 242.345M

My code is below. I am writing code to group by and then average another row, which is what I have down below. But instead of passing the whole function everytime, I want to be able to just pass in the CSV or data as the function parameter in one line and do this for multiple times for different data sets. As you can see from "row.income" and ".Rows" I am using a TYPE, but when I try to call the function later with a TYPE, it gives me an error. How would I go about doing this?

FYI the errors are that the rows do not exist because I am using "values" as a parameter and not the actual CSV file, because I call that later. This is the error I need to fix, to be able to call a specific row in the function, while passing a type as the parameter.

// When I try to call the function with Type

type Csvdata = CsvProvider<somefile>

state Csvdata

// This results in an error 

解决方案

You cannot pass a type as a parameter in the way you describe. You can pass a generic type parameter, but to do what you want, the syntax will be a little different, because you'll need to use Statically Resolved Type Parameters on an inline function. Using the example csv.txt with the following data:

name,income
bob,134.56
mary,350.13

The implementation would look like this:

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> ()

Here, ^t is the specific type of the provider for your file, in this case Csvdata, but which we are only requiring to have a method called GetSample that returns another type, ^a. ^a is the type of the type provider itself, in this case, CsvProvider<"csv.txt">, but which we are only requiring to have a property called Rows that gives us a sequence of some type ^b. Finally, ^b represents the type of each row, in this case Csvdata.Row, but which we are only requiring to have a decimal property called Income.

By using the type constraints in this way, you can pass any combination of types that meet the constraints, so it will work for any CsvProvider for any CSV file that has an Income column.

Running the code for our sample file gives the following output:

val it : decimal = 242.345M

这篇关于如何在F#中将类型作为函数参数传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆