LINQにはいくらですか?
-
07-07-2019 - |
質問
LINQを検討していますが、クエリ言語は(少なくとも表面的には)Haskellや他のFP言語(特に 'mapの一般化Scalaでは「for」。これは正しいです?構文にはこれ以上のものがありますか?私が読んでいる本の息をのむような音色(「Essential LINQ」)からは、ここに何か新しいものや革新的なものがあるように思えます。
LINQを実装するためのバックエンド、パイプライン、1次式ツリー、型などはすべてありますが、私の質問はクエリ言語自体に関するものです。
乾杯
ジョー
解決
機能的には、LINQはモナドを表現するための構文の単純化に他なりません。 Linq to Objects(リスト内包表記-これでも既に非常に便利です)は、これまでお話ししてきましたが、これを適用するのは 1つだけです(HaskellのList-Monadと同様)。
書く場合
from x in expr1
from y in expr2
select x + y
それはただの
do
x <- expr1
y <- expr2
return $ x + y
Haskellで。
実行される具体的なことは、ユーザー定義の Linq-providers (Extension-Methods)に依存しますが、その Linq.Enumerable
は IEnumerable
s。
1つ提供することにより、完全に新しいLINQセマンティクスを作成できます。
例:失敗する可能性のある計算(null値)の 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は非常に強力になり、表現できるようになります-
- データベースアクセス
- 非同期プログラムフロー
- Maybe-Monads
- 内包表記のリスト
- 再帰降下パーサー
- 継続
- ミニ言語
- 並列計算(PLinq)
一部のリンク:
固定小数点コンビネータと組み合わせて、Linqは完全な機能ミニ言語( Linq raytracer )。
ScalaとF#の両方がfor-comprehensionsと計算式で同様の概念を持っていることに注意してください。どちらもモナドの抽象化です:
スカラ:
for (x <- expr1
y <- expr2) yield x + y
F#:
monad {
let! x = expr1
let! y = expr2
return x + y
}
他のヒント
息切れは、おそらく「明白な」すべてのものを対象としています。いくつかのもの(式ツリーなど)は本当に優れています。言語は単なるアクセス手段です。 throw
キーワード、またはそれが公開する機能に興奮しますか?
それについての本を読むことに加えて、あなたはすでにLINQを使用しましたか?私は毎日のプログラミング作業でそれが非常に時間の節約になることがわかりました。私にとって、これは抽象化の次のステップであり、XMLやSQLなどの異なるデータソースを組み合わせて、同じ「言語」でそれらを操作するために使用できます。
さらに、機能的なプログラミングと、 LINQ。
LINQのコアであるクエリ構文は、実際には大きなスコープではありません。メソッドとラムダへの非常にリテラルな翻訳です-
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を使用できるようにするために必要な式ツリーのサポートです。つまり、どちらでもコンパイルできるラムダ式記述されたコードを表すオブジェクトモデルへのデリゲートまたはへ。興味深いことに、この同じ考え方は、4.0でのDLR解像度の動作方法にも反映されています。
LINQは、 Erik Meijerとして、HaskellDBに触発されました多数述べている、例えば使用済みプログラミング言語セールスマンの告白(Getting Haskellに夢中になった大衆)、それ自体は新しい概念ではありません。同じ言語を使用して異なるソースを照会することはある程度革新的ですが、ネストされたリレーショナルモデルがXML、オブジェクト、およびリレーショナルデータベースをカバーするという事実は、以前に研究者によって示されました。私にとって非常にクールなのは、人気のある汎用の、主にオブジェクト指向の言語に組み込まれていることです。
Scala IMHOには、同様のものを組み込む能力があります。これまでのところ、Scalaには Stefan Zeiger のScalaQueryと Daniel Spiewak の ScalaQL 。LINQの足跡をたどります。