F#类型提供程序,它们是如何工作的?

39
我不太理解类型提供程序,即使看了Don Symes的pdc视频http://player.microsoftpdc.com/Session/04092962-4ed1-42c6-be07-203d42115274
我的理解是,你可以获得Twitter、Excel等现成的类型提供程序...
如果我有自定义的Xml结构,那我需要为此实现自己的类型提供程序吗?这与创建自己的自定义映射器有何不同?
3个回答

40

假设你有一些在世界上的任意数据实体。 以这个例子来说,我们假设它是一个电子表格。

同时,假设你有一种获取/推断数据模式/元数据的方式——也就是说,你可以知道类型(例如 double 或 string)和关系(例如这一列表示“工资”)以及元数据(例如这张表是为了 2009 年 6月的预算)。

类型提供程序让你编写一种'虚拟库',了解某种类型的数据实体(例如电子表格),并将其作为编译器/IDE 工具链的一部分使用,这样你就可以编写这样的代码:

mySpreadsheet.ByRowAndColumn.C4
或其他什么东西,并获得Intellisense(自动完成)和工具提示(例如,将单元格C4描述为Bob的薪水),以及静态类型(例如,将其作为double或string或任何其他类型)。基本上,这为您提供了静态类型对象模型的工具支持和各种动态或代码生成系统的易用性支持,同时在两者方面都有所改进。 “代价”是需要有人编写shim库(“类型提供程序”),但许多此类提供程序都非常通用(例如一种支持OData、Excel、WMI等内容),因此少量的类型提供程序库便可使大量世界数据可在您的编程语言中以静态类型和一流的工具支持下使用。
该架构是一个开放式编译器,其中提供程序作者实现了一个小接口,允许他们将新名称/类型注入到编程上下文中。类型提供程序可能只是您传递给编译器的另一个库(在项目中引用,用-r表示),具有额外的元数据,将其标记为参与开发的编译/IDE/codegen部分的类型提供程序。
我不知道您XML示例中的“自定义映射器”到底是什么,无法进行比较。

你有没有关于类型提供程序何时可用的信息?谢谢。 - jlezard
我所说的自定义映射器是指将XML文件映射到强类型对象模型的库。我看不出这样的库和类型提供程序库之间有什么大的区别。 - terjetyl
因为可以为XSD文件编写一个类型提供程序,所以您可以获得强类型、可发现的访问任何与任何XSD兼容的XML文件,而无需编写映射器或对象模型。 - Joel Mueller
请注意,我假设“自定义映射器”涉及“代码生成”(这带有其自身的负面影响),并且是用于XML的特定工具。而类型提供程序则是一种开放机制,任何人都可以使用相同的接口/机制为任何类型的数据编写提供程序,而不是依赖于某些特定领域/数据的固定工具集。 - Brian

9

我知道这是一个老问题,但现在 F# 3.0 已经发布,Type providers(类型提供程序)可用。有一篇白皮书对此进行了解释。我们还有来自微软的代码,可以让您看到内部情况。

http://www.infoq.com/news/2012/09/fsharp-type-providers


6
类型提供程序使用F#的引用作为(有效地)编译器插件,可以根据编译时的元数据生成代码。这使您能够(例如)读取一些JSON、数据库模式或某个XSD等,然后生成F#类来模拟该元数据所表示的域。
在创建它们方面,我写了几篇博客文章,可能会对您有兴趣,从Type Providers from the Ground Up开始。

类型提供程序实际上与 IL 发生器没有任何关系(生成型提供程序可以将其用作实现细节,但擦除提供程序根本不涉及 IL)。 - kvb
从ProvidedTypes.fs中我所看到的,即使在擦除提供程序中,您为方法和属性提供的引用作为调用代码添加到程序集中时也会转换为IL。当然,类型本身不会被转换。 - mavnn
目前我没有时间进一步研究,但这让我感到惊讶——原始API是围绕引用设计的,编译器使用像(|ProvidedCallExpr|_|)这样的模式,在est.fs中定义,它从提供程序中获取引用并将其包装,然后在typreIns.fs中将其转换为适当的AST节点。 - kvb
@kvb 我相信你是对的 - 我已经修改了答案以匹配。我之前误解了一些ProvidedTypes代码。 - mavnn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接