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

Tim*_*mwi 3 f# api-design language-design

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

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

des*_*sco 7

因为LINQ方法位于System.Core =>仅在.NET 3.5及更高版本上可用,而F#base库支持.NET 2.0+.

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


Bri*_*ian 7

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

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

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

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


gan*_*tas 6

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

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

C#

seq.Where(...)
   .Select(...)
   .Take(...)
Run Code Online (Sandbox Code Playgroud)

F#

seq
|> Seq.filter ...
|> Seq.map ...
|> Seq.take ...
Run Code Online (Sandbox Code Playgroud)