F#类型提供程序和数据处理

标签 f# type-providers

在上一个问题(Working with heterogenous data in a statically typed language)中,我询问了F#如何处理数据分析中的标准任务,例如处理无类型的CSV文件。动态语言擅长于诸如以下的基本任务

data = load('income.csv')
data.log_income = log(income)

在F#中,最优雅的方法似乎是问号(?)运算符。不幸的是,在此过程中,我们丢失了静态类型输入,仍然需要在此处和此处进行类型注释。

F#最令人兴奋的 future 功能之一是Type Providers。在类型安全性损失最小的情况下,CSV类型提供程序可以通过动态检查文件来提供类型。

但是数据分析通常并不止于此。我们经常通过一系列操作来转换数据并创建新的数据集。我的问题是,如果我们主要操作数据,类型提供者可以提供帮助吗?例如:
open CSV // Type provider
let data = CSV(file='income.csv') // Type provider magic (syntax?)
let log_income = log(data.income) // works!

这可行,但会污染全局 namespace 。考虑添加列而不是创建新变量通常更自然。有什么办法吗?
let data.logIncome = log(data.income) // won't work, sadly.

目标创建新的派生数据或清理后的数据集时,类型提供程序是否可以避免使用(?)运算符?

也许像这样:
let newdata = colBind data {logIncome = log(data.income)}  // ugly, does it work?

还有其他想法吗?

最佳答案

简短的答案是“否”,长答案是"is"(但您不希望得到结果)。要记住的关键是 F#是静态类型的语言,句号

对于您提供的代码,newData有什么类型?如果无法在编译时将其固定下来,则需要诉诸于Obj或从Obj进行强制转换。

// newdata MUST have a static type, even if obj
let newdata = colBind data {logIncome = log(data.income)}  

想象一下colBind具有以下特征:
val colBind: Thingey<'a> -> 'b -> Thingey2<'a, 'b>

这实际上会以某种方式起作用,但它不会普遍起作用。因为最终您将需要在编译时不存在的类型。

F#类型提供程序允许您静态生成来自标准编译时环境外部的数据数据。但是,类型仍然是静态的。无法在运行时动态更改这些类型*。

*You can modify the object at runtime using shenanigans such as DynamicObject. However, once you start going down that path you lose all the benefits of a statically typed language such as Intellisense. (Which is a major reason for using F# in the first place.)



从概念上讲,您想要做的很简单。 System.Data.DataTable类型已经具有存储表格数据的概念,并且能够动态添加列。但是由于添加的列的类型信息在编译时未知,因此必须将存储在这些列中的内容视为Obj并在运行时进行强制转换。

关于F#类型提供程序和数据处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4503921/

相关文章:

f# - "a -> b -> (a -> b -> c) -> c"应用两个参数是标准函数概念吗?

.net - 类型不匹配错误。 F# 类型推断失败?

f# - 调用 F# 异步工作流程时,我可以避免定义临时标签吗?

scala - 当参数是对象类型时,如何在 F# 中要求多个接口(interface)?

f# - 在可移植类库中使用 F# JsonProvider 失败

f# - TypeProvider 给出了意想不到的开发时行为

f# - 模式匹配语法中的歧义

linq - 如何将U放入F#类型提供者CRUD中?

f# - 如何引用 TypeProvider 创建的 'generated' 类型

F#如何创建提供类型的实例