为什么F#的Collections.Seq模块基本上重新实现了所有Enumerable扩展方法?

时间:2010-09-23 11:18:11

标签: f# language-design api-design

为什么Collections.Seq module有很多方法看起来等同于System.Linq.Enumerable中声明的扩展方法?为什么F#的设计者觉得需要为所有这些创建一个新的命名空间和新的/不同的名称,而不是重用.NET中已经存在的名称?

(如果他们需要一些额外的方法,他们为什么不将它们添加到System.Linq.Enumerable?)

3 个答案:

答案 0 :(得分:7)

因为LINQ方法位于System.Core =>仅适用于.NET 3.5及更高版本,F#基本库支持.NET 2.0 +。

另外,Seq函数的使用方式(通过管道)对于LINQ Enumerable扩展的点样式的F#代码更自然。

答案 1 :(得分:7)

这里有一些其他不错的答案,但我的观点是短暂的

  • 部分应用程序(.NET方法是tupled,F#方法是curry)
  • 重载(.NET方法重载,F#let-bound值不能)

基本上,一旦你习惯了F#习语,你就会发现.NET API对于F#风格的编程很糟糕。 F#主要面向流水线式编程(需要部分应用传入序列作为最后一个参数)和类型推理(与重载相互作用很严重)。

所以F#有自己的库,可以很好地与F#配合使用。 (这是一个快速解码器环blog。)

答案 2 :(得分:6)

另一个原因是在F#中使用管道运算符(|>,< |,>>)。

.NET扩展方法是basicaly为第一个参数提供部分应用程序。 F#pipelining oprators partial适用于最后一个参数。 Seq模块中的所有函数都将序列作为最后一个参数。

C#

seq.Where(...)
   .Select(...)
   .Take(...)

F#

seq
|> Seq.filter ...
|> Seq.map ...
|> Seq.take ...