我正在研究LINQ,并且查询语言出现(至少在表面上)只不过是在Haskell和其他FP语言中找到的地图和/或列表推导的实现(特别是'map的概括) '和'为'在Scala中)。它是否正确?语法是否比这更多?从我正在阅读的这本书(“Essential LINQ”)的令人窒息的语气来看,这里似乎有一些新的或创新的东西。
有实现LINQ的整个后端,管道,一阶表达式树和类型等,但我的问题是关于查询语言本身。
干杯
乔
答案 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可以非常强大,并允许您表达 -
一些链接:
结合定点组合器,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 Spiewak的ScalaQL,它遵循LINQ的脚步。