8

クエリ式に新しいキーワードを拡張/追加する方法に関するドキュメントや例はありますか? これは可能ですか?

たとえば、リード/ラグ演算子を追加したいと思います。

4

2 に答える 2

14

@pad が言及した Rx フレームワークのクエリ ビルダーに加えて、クエリ式を含む計算式について、F# チームの Wonseok Chae による講演もあります。会議が録画されたかどうかはわかりませんが、.NET IL コードを生成するためのクエリ構文に関する優れた例を含む非常に詳細なスライドがあります。

標準の F# クエリ ビルダーのソース コードは、サポートされている操作の種類と、それらに属性で注釈を付ける方法を見つけるためのおそらく最適なリソースです。

whereおそらく必要になる主要な属性は、次の句で示されます。

[<CustomOperation("where",MaintainsVariableSpace=true,AllowIntoPattern=true)>]
member Where : 
  : source:QuerySource<'T,'Q> * 
    [<ProjectionParameter>] predicate:('T -> bool) -> QuerySource<'T,'Q>

CustomOperation属性は操作の名前を定義します。(非常に重要な) パラメータMaintainsVariableSpaceを使用すると、操作が入力として受け取るのと同じタイプの値を返すことができます。その場合、以前に定義した変数は操作後も引き続き使用できます。例えば:

query { for p in db.Products do
        let name = p.ProductName
        where (p.UnitPrice.Value > 100.0M)
        select name }

ここでは、入力をフィルタリングするだけで、リスト内の値を変換しないため、変数pnameはその後も引き続きアクセスできます。wherewhere

最後に、 をProjectionParameter使用すると、p.UnitValue > 100.0Mを実際にコンテキスト (使用可能な変数) を取得してこの式を評価する関数に変換する必要があります。この属性を指定しない場合、操作は次のように引数の値を取得するだけです:

query { for p in .. do
        take 10 }

ここで、引数10は で値を使用できない単純な式ですp

于 2012-12-11T22:12:40.460 に答える
6

この言語のかなりクールな機能。QuerySource を照会するために逆を実装しただけです。

簡単な例ですが、単なるデモンストレーションです。

module QueryExtensions

type ExtendedQueryBuilder() =
    inherit Linq.QueryBuilder()
    /// Defines an operation 'reverse' that reverses the sequence    
    [<CustomOperation("reverse", MaintainsVariableSpace = true)>]
    member __.Reverse (source : Linq.QuerySource<'T,System.Collections.IEnumerable>) =
        let reversed = source.Source |> List.ofSeq |> List.rev
        new Linq.QuerySource<'T,System.Collections.IEnumerable>(reversed)


let query = ExtendedQueryBuilder()

そして今、それが使われています。

let a = [1 .. 100]

let specialReverse = 
    query {
        for i in a do
        select i
        reverse
    }
于 2012-12-11T22:44:36.767 に答える