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];}