F# -- Quotation 表达式(二)

下面我们看看如何将F# 中的Quotation表达式转为LINQ表达式, 这个也就是上一篇中说说的第三个功能。

在实现此功能前,我们学要从Codeplex上将F# 的一个扩展包下在到本地,此扩展为FSharp.PowerPack. 这个扩展包对F#作了很大的扩展,其中包括很多新的不可变类型, 以及一些数学中常常用到的矩阵,实数复数等等的相关类型及操作。值得注意的是此扩展包以前版本中的一些功能已经被内置到F#3.0中了。

下面我们看看代码:

#if INTERACITVE
#r @"C:\Users\v-shuzhu\Desktop\bin\gac\FSharp.PowerPack.dll"
#r @"C:\Users\v-shuzhu\Desktop\bin\gac\FSharp.PowerPack.Linq.dll"
#endif
open System
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq
open System.Linq.Expressions
open Microsoft.FSharp.Linq.QuotationEvaluation


let toLambda (exp : Expr<'a -> 'b>) =
    //调用Microsoft.FSharp.Linq.QuotationEvaluation中的方法 将Quotation表达式转为Linq表达式,其结果为型如:
    (*val it : Expression =
        ToFSharpFunc(x => (x + 1))
        {Arguments = seq [x => (x + 1)];
         CanReduce = false;
         Method = Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32] ToFSharpFunc[Int32,Int32](System.Converter`2[System.Int32,System.Int32]);
         NodeType = Call;
         Object = null;
         Type = Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32];}*)
    let linq = exp.ToLinqExpression()
    let call = linq :?> MethodCallExpression
    let lambda = call.Arguments.[0] :?> LambdaExpression
    Expression.Lambda<Func<'a,'b>>(lambda.Body,lambda.Parameters)

let exp : Expr<int -> int> = <@ fun x -> x + 1 @>
let CsLinq = toLambda(exp) 

 本例中的运行结果如下:

val exp : Expr<(int -> int)> =
  Lambda (x, Call (None, op_Addition, [x, Value (1)]))
val CsLinq : Expression<Func<int,int>> = x => (x + 1)

CsLinq的具体信息:

val it : Expression<Func<int,int>> =
  x => (x + 1) {Body = (x + 1);
                CanReduce = false;
                Name = null;
                NodeType = Lambda;
                Parameters = seq [x];
                ReturnType = System.Int32;
                TailCall = false;
                Type = System.Func`2[System.Int32,System.Int32];}

posted @ 2012-12-24 16:24  ZackZhou  阅读(372)  评论(0编辑  收藏  举报