Haskell和LINQ之间有什么联系吗?

时间:2011-01-13 18:07:18

标签: c# linq haskell

我使用LINQ在C#中编写了一些查询。过了一会儿,我开始使用Haskell一点点,这是一种函数式编程语言(一种不那么受欢迎的语言),而对我来说似乎它们几乎都是一样的。但我不确定这一点。如果有人比我更多地使用它们,他们能不能告诉我它们在编程原理上是否几乎相同?

另外,LINQ可以被认为是函数式编程吗?

感谢。

4 个答案:

答案 0 :(得分:56)

  对我而言,似乎两者几乎都是一回事。但我不确定这一点。如果有人比我更多地使用它们,他们能不能告诉我它们在编程原理上是否几乎相同?

是的,LINQ查询理解的设计受Haskell设计的影响很大。当我们设计LINQ时,Haskell专家Erik Meijer加入了C#语言设计委员会;他的见解非常宝贵。 (我在这个过程结束时加入了设计团队,所以不幸的是我没有参与所有有趣的曲折,这些设计经历了多年;它开始变得更加传统OO而不是最终结束!)< / p>

如果您最近对Haskell进行了认真的探索,那么您可能已经熟悉了monad的想法。 LINQ语法专门设计用于使序列monad上的操作感觉自然,但实际上实现更通用; C#调用“SelectMany”是对任意monad的“绑定”操作的略微修改形式。实际上,您可以对任何monad as my colleague Wes describes here使用查询理解,但这样做看起来很奇怪,我建议在生产代码中反对它。

  

另外,LINQ可以被认为是函数式编程吗?

是的,LINQ深受功能编程思想的影响。它旨在将函数视为一等对象,强调计算副作用等等。

答案 1 :(得分:9)

值得一看Erik Meijer Lecture。这是对它的描述。

  

我们开始了C9讲座   进入功能世界   用功能语言编程   lambda的纯粹主义者和大祭司   微积分,Erik Meijer博士(你可以   感谢Erik的许多功能   已经出现的结构   像C#和VB.NET这样的语言。当你   使用LINQ,谢谢Erik   安德斯)。

答案 2 :(得分:3)

C#确实获得了函数式编程的某些方面。首先是lambda语句,作为匿名委托实现。您现在不再需要将方法定义为属于对象,并且您可以以与任何其他变量类似的方式定义方法。这允许许多功能类型的构造:

var mult = (a,b)=>a*b;
var square = (a)=>Math.Pow(a,2);
var multandsquare = (a,b)=>square(mult(a,b));

//None of the above give a lick about what a and b really are, until...
multandsquare(5,3); //== 225

函数式编程的基本范例 - 基本上可以告诉计算机做的任何事情都可以用高阶函数来表达 - 可以应用于C#程序,特别是现在C#实际上具有更高阶函数。编译器将强制你至少有一个类至少有一个公共main方法(这就是OO的工作方式),但从那时起你只能根据函数来定义几乎所有东西(def:“方法”的子类)采用N个参数并产生1个输出,没有“副作用”)实例化为lambdas。

Linq确实有一些功能结构。基本上它的方法链范例是monadic处理的一个例子,它是通过操作封装在函数语言中(现在在C#中)来构造操作序列的。在IEnumerable上调用Linq方法会返回另一个IEnumerable,它实际上是一个不同的具体类,它包含源Enumerable的句柄和一些要执行的lambda。您可以非常简单地用函数式语言复制它;它是源的元组(本身是当前元素和其他所有元素的元组)和一个执行的函数,它将源元组转换为结果,一次一个元素(在Linq中,因为它将在函数中实现) language,是将某些操作嵌套到定义的“汇总”函数中)。调用必须产生实际答案的方法(具体的类型化结果),并对所有这些函数进行充分评估,以产生所需的结果。

答案 3 :(得分:1)

  

也可以考虑LINQ   函数式编程?

LINQ意味着一种功能风格,因为它类似于SQL select,原则上它是只读的。但是,因为.NET中的LINQ子句是由普通的CLR例程实现的,所以没有什么可以阻止LINQ表达式修改状态。

另一方面,Haskell是一种“纯粹”的函数式语言,因此表达式无法修改全局状态。尽管可以执行IO和图形操作,但这些操作都是使用与.NET中任何内容完全不同的惯用语来实现的 - 包括F#,它允许您或多或少透明地使用程序样式。