LINQ有多少钱?

时间:2009-09-13 16:16:14

标签: c# linq scala functional-programming

我正在研究LINQ,并且查询语言出现(至少在表面上)只不过是在Haskell和其他FP语言中找到的地图和/或列表推导的实现(特别是'map的概括) '和'为'在Scala中)。它是否正确?语法是否比这更多?从我正在阅读的这本书(“Essential LINQ”)的令人窒息的语气来看,这里似乎有一些新的或创新的东西。

有实现LINQ的整个后端,管道,一阶表达式树和类型等,但我的问题是关于查询语言本身。

干杯

5 个答案:

答案 0 :(得分:25)

从功能上说,LINQ只不过是表达monad的句法简化。 Linq to Objects(List-comprehensions - 即使这已经非常有用),你一直在谈论它,只是一个可能的应用程序(类似于Haskell中的List-Monad)。 / p>

如果你写

from x in expr1
from y in expr2
select x + y

它只不过是

do
    x <- expr1
    y <- expr2
    return $ x + y

在Haskell。

完成的具体事情取决于用户定义的 Linq-providers (扩展方法),其中Linq.Enumerable只是一个涉及IEnumerable的实现。

通过提供一个,您可以为您的类型创建全新的LINQ语义。

示例:给定Option类型的计算可能失败(可空值),可以定义一个Linq提供程序来查询它们。

public static class MaybeExtensions
{
public static Option<T> ToMaybe<T>(this T value)
{
    return Option<T>.Some(value);
}

public static Option<U> SelectMany<T, U>(
    this Option<T> m, 
    Func<T, Option<U>> k)
{
    return !m.IsNone ? Option<U>.None : k(m.Value);
}

public static Option<V> SelectMany<T, U, V>(
    this Option<T> m, 
    Func<T, Option<U>> k, 
    Func<T, U, V> s)
{
    return m.SelectMany(x => k(x).SelectMany(y => s(x, y).ToMaybe()));
}
} 

现在允许我们编写这样的代码:

var sum = from x in ReadNumber("x")
          from y in ReadNumber("y")
          select x + y; 

如果所有计算都成功,计算将只返回一个值,否则在第一次失败时计算失败。

结合表达式树,Linq可以非常强大,并允许您表达 -

  1. 数据库访问
  2. 异步程序流程
  3. 也许-单子
  4. 列表理解
  5. 递归下降解析器
  6. 延续
  7. 迷你语言
  8. 并行计算(PLinq)
  9. 一些链接:

    结合定点组合器,Linq提供了一个完整的功能性迷你语言(Linq raytracer)。

    请注意,Scala和F#在for-comprehensions和计算表达式中都有类似的概念,它们都是monadic抽象:

    Scala的:

    for (x <- expr1
         y <- expr2) yield x + y
    

    F#:

    monad {
        let! x = expr1
        let! y = expr2
        return x + y
    }
    

答案 1 :(得分:5)

气喘吁吁可能适用于所有“明显”的东西,其中一些(如表达树)真的很棒。语言只是一种访问手段;你对throw关键字或它所公开的功能感到兴奋吗?

答案 2 :(得分:4)

除了读一本关于它的书之外,你是否已经使用过LINQ?我发现它在我的日常编程工作中节省了很多时间。对我来说,这是抽象的下一步,它可以用来组合不同的数据源,如XML或SQL,并以相同的“语言”使用它们。

此外,我推荐这个interview with Anders Hejlsberg关于函数式编程和LINQ。

答案 3 :(得分:3)

查询语法LINQ的核心实际上并不是很大。它只是一些非常文字的翻译,方法和lambdas - 所以

var qry = from x in src
          where x.Foo == "foo"
          select x.Bar;

字面意思

var qry = src.Where(x => x.Foo == "foo").Select(x => x.Bar);

它对扩展方法一无所知(虽然它们是最常见的(但不是唯一的)实现),而且没有关于Expression等等。关键字的数量(以及数量)所需的方法实现)并不大。 Jon曾试图在1小时内实现所有这些(在现场演示中)。他没有做得太糟糕;-p


也许LINQ中更令人印象深刻的部分是允许LINQ用于数据库所需的表达式树支持 - 即可以编译 的lambda表达式委托到代表所编写代码的对象模型。有趣的是,同样的想法深入探讨了DLR解决方案在4.0中的工作方式。

答案 4 :(得分:2)

LINQ的灵感来自于HaskellDB,Erik Meijer已经多次声明,例如:在Confessions of a Used Programming Language Salesman (Getting the Masses Hooked on Haskell),所以它本身并不是一个新概念。使用相同的语言查询不同的来源在某种程度上是创新的,尽管之前研究人员已经展示了嵌套关系模型涵盖XML,对象和关系数据库的事实。对我来说,最酷的是它已被嵌入到流行的,通用的,主要面向对象的语言中,这在以前是没有做过的。

Scala恕我直言,有能力纳入类似的东西。到目前为止,对于Scala,我们有Stefan Zeiger的ScalaQuery和Daniel SpiewakScalaQL,它遵循LINQ的脚步。