我正在研究LINQ,查詢語言出現(至少在表面上)只不過是在Haskell和其他FP語言中找到的映射和/或列表解析的實現(特別是'map'的泛化)和Scala中的'for')。它是否正確?除此之外,還有更多的語法嗎?從我正在閱讀的書(「Essential LINQ」)的令人喘不過氣的語氣看來,這裏看起來有些新穎或創新。LINQ有多少?
還有整個後端,管道,一階表達式樹和類型等來實現LINQ,但我的問題是關於查詢語言本身。
乾杯
喬
我正在研究LINQ,查詢語言出現(至少在表面上)只不過是在Haskell和其他FP語言中找到的映射和/或列表解析的實現(特別是'map'的泛化)和Scala中的'for')。它是否正確?除此之外,還有更多的語法嗎?從我正在閱讀的書(「Essential LINQ」)的令人喘不過氣的語氣看來,這裏看起來有些新穎或創新。LINQ有多少?
還有整個後端,管道,一階表達式樹和類型等來實現LINQ,但我的問題是關於查詢語言本身。
乾杯
喬
從功能上講,LINQ只不過是表達單子的句法簡化。對象(列表解析 - 即使這已經非常有用),你一直在談論,只是一個可能應用程序(類似List-Monad在Haskell)。
如果你寫
from x in expr1
from y in expr2
select x + y
它只不過是
do
x <- expr1
y <- expr2
return $ x + y
在Haskell
。
做到這一點具體的事情取決於用戶定義的LINQ提供程序(擴展的方法),其中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 (x <- expr1
y <- expr2) yield x + y
F#:
monad {
let! x = expr1
let! y = expr2
return x + y
}
除了看書吧,你已經使用LINQ?我發現它在我的日常編程工作中是一個巨大的倍頻器。對我來說,這是抽象的下一個步驟,它可以用來合併不同的數據源,如XML或SQL,並以相同的「語言」使用它們。
此外,我建議這個interview with Anders Hejlsberg關於函數式編程和LINQ。
感謝您的回覆和鏈接,我會讀它。是的,我已經使用了一些(我發現它確實非常有用),但我使用的方式與我一直在使用map和Scala中的方法相同。我問這個問題是因爲它們的相似之處,並且想知道它們有多深。 – Joe 2009-09-13 16:52:52
LINQ的靈感由HaskellDB,因爲Erik Meijer已經無數地陳述,例如在Confessions of a Used Programming Language Salesman (Getting the Masses Hooked on Haskell),所以它本身並不是一個新概念。儘管嵌套關係模型涵蓋了XML,對象和關係數據庫這一事實,研究人員以前已經展示過,但使用相同的語言來查詢不同的數據源在某種程度上是創新性的。對我而言,非常酷的是它已經嵌入到一個流行的,通用的,主要面向對象的語言中,這是以前沒有做過的。
斯卡拉恕我直言,有能力合併類似的東西。到目前爲止,對於Scala,我們有Stefan Zeiger的ScalaQuery和Daniel Spiewak的ScalaQL,它遵循LINQ的腳步。
感謝您的鏈接,它們看起來很有趣。 – Joe 2009-09-13 16:59:34
查詢語法LINQ的核心範圍並不是很大。這只不過是一些非常字面翻譯,方法和lambda表達式 - 所以
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中的工作方式。
一個非常有用的觀點。感謝澄清。 – Joe 2009-09-13 19:41:59
謝謝你的信息。我會研究這些線索。 – Joe 2009-09-13 16:57:10
真的很好,總結一個很好的,易於掌握的例子。 +1 – 2009-09-13 17:07:50
繼續在raytracer鏈接上,下面是完全在單個LINQ語句中實現的相同raytracer:http://tirania.org/blog/archive/2007/Nov-16.html – JulianR 2009-09-13 17:37:39