在F#中使用LINQ?

Arm*_*age 14 .net linq f#

鉴于像F#这样的语言的基本语法和语义已经设计为准确提供LINQ为C#/ VB提供的添加内容,为什么在F#编程时我应该使用LINQ?我获得了什么,我可能会失去什么?

Bri*_*ian 19

LINQ有两个方面.一个是语言方面,例如在C#中存在(上下文)关键字from,select并且where您可以使用它来编写相当类似SQL的代码,这些代码对IEnumerables和whatnot进行查询.这是一个相对较薄的语法糖层,可以转换为LINQ库调用SelectSelectManyWhere等等.

然后就是IQueryable方面,这使得相同的代码可以被实现为一个IQueryable,它实际上非常类似于引用机制,因为它有助于构造查询的语法树.这是必不可少的,因为不同的提供者可以插入行为以自己的方式"编译"代码,例如,SQL提供者可以获得"整个查询"视图,并使用将在其上运行的良好查询计划组成查询.服务器(与将SQL数据库视为IEnumerable行的简单方法相反,只是加载内存中的所有行并在客户端应用程序内的.NET中过滤它们,这会严重或简单地落在大数据上).

第一个方面只是语法糖和诸如此类的东西.F#2.0(VS2010中的F#版本)没有LINQ的内在支持,但PowerPack有一个LINQ桥接器,因此您可以使用普通F#Seq组合器的F#引用来表达LINQ查询.

然而,第二个方面是整体技术方面更重要的一点.LINQ是关于验证查询以便程序员可以声明性地指定意图,然后各种提供者可以插入系统并将该意图转换为相应的数据后备存储的有效执行计划..NET 3.5.表达式树类型是LINQ这一重要方面的"接口",因此任何给定的编程语言都需要某种方式让程序员编写将生成这些表达式树的表达式.

所以我觉得原来的问题没有意义.使用LINQ的基本原因是因为您希望查询SQL数据库(或OData源,或...),以便查询在服务器上高效运行(或者不必不必要地使用一百万个重复的HTTP请求,或者......),并且您希望以一种不需要您了解这些技术细节的方式这样做(各种LINQ后端提供商都拥有所有针对特定领域的智能).语法主要只是语法,不同的语言可能有不同的糖(或糖化机制)来创建LINQ查询,其方式与给定的编程语言惯用.

  • 我对LINQ的主要兴趣是使用它,因此我可以将C#LINQ语句替换为复杂的命令式逻辑,通常是针对简单的内存中C#类型.使用F#时,对此的需求被消除了,因为我可以使用该语言的内置语法.所以我最初的问题更像是"为什么使用带有F#的LINQ",听起来你的回答是"对于LINQ擅长的其他事情" (3认同)

blu*_*ucz 11

LINQ,从语言的角度来看(C#的特殊来自...语法)大多是不必要的,因为F#能够非常简洁地表示类似LINQ的数据转换.我怀疑C#sugar剩下的大部分用途是重新组织代码,因此C#可以键入LINQ查询,而不必强制用户提供类型注释或手动执行eta-expansion.这也是F#中不必要的.

至于在F#中使用System.Linq命名空间,我不推荐它.对于成员访问,F#类型推断变得非常愚蠢.我怀疑使用System.Linq需要比使用相应的F#库更明确的类型注释.即使在类型推断成功的情况下,与本机库相比,未经证实的CLR样式的API通常在F#中感觉很重且不合适.


kog*_*oia 9

我同意@blucz的回答,不推荐,但如果你真的想要,它看起来像这样:

进口SystemSystem.Linq

open System
open System.Linq
Run Code Online (Sandbox Code Playgroud)

封装一些LINQ扩展方法

let select  f xs = Enumerable.Select(xs, new Func<_,_>(f))
let where   f xs = Enumerable.Where(xs, new Func<_,_>(f))
let orderBy f xs = Enumerable.OrderBy(xs, new Func<_,_>(f))
Run Code Online (Sandbox Code Playgroud)

并使用它

[1..100] 
|> where (fun x -> x > 2) 
|> select (fun x -> x * 2) 
|> printfn "%A"
Run Code Online (Sandbox Code Playgroud)