10

Expr<'a -> 'b>次のスニペットを使用して、型の引用を Linq 式に変換できます。

/// Converts a F# Expression to a LINQ Lambda
let toLambda (exp:Expr) =
    let linq = exp.ToLinqExpression() :?> MethodCallExpression
    linq.Arguments.[0] :?> LambdaExpression

/// Converts a Lambda quotation into a Linq Lamba Expression with 1 parameter
let ToLinq (exp : Expr<'a -> 'b>) =
    let lambda = toLambda exp
    Expression.Lambda<Func<'a, 'b>>(lambda.Body, lambda.Parameters)

ここで、 type の引用符を変換したい、Expr<'a * 'b -> 'c>またはおそらくtypeExpr<'a -> 'b -> 'c>の Linq Lambda Expression に変換したいと考えていExpression<Func<'a,'b'c>>ます。

これどうやってするの?

よろしく、フォーキ

4

1 に答える 1

13

これが F# PowerPack で利用可能な LINQ モジュールで直接サポートされているかどうかはわかりません。ただし、F# ライブラリによって生成された LINQ 式の独自の後処理を実装して、通常の形式の C# ラムダ関数に変換することができます。

LambdaExpression次の関数は、1 つのパラメーター (つまり、F# トランスレーターによって生成される構造体) の複数の入れ子式として構築される LINQ 式を受け取り、パラメーターのリストと最も内側の式の本体を返します。

let rec translateExpr (linq:Expression) = 
  match linq with
  | :? MethodCallExpression as mc ->
      let le = mc.Arguments.[0] :?> LambdaExpression
      let args, body = translateExpr le.Body
      le.Parameters.[0] :: args, body
  | _ -> [], linq

これを使用して、次のようなFunc型から通常のデリゲートを取得できます。int -> int -> int -> int

let linq = (<@@ fun a b c -> (a + b) * c @@>).ToLinqExpression()
let args, body = translateExpr liq
let f = Expression.Lambda<Func<int, int, int, int>>
          (body, args |> Array.ofSeq)
f.Compile().Invoke(10, 11, 2)
于 2010-04-21T14:50:45.977 に答える