评估F#中的引用表达式

时间:2009-05-11 18:30:01

标签: f# quotations

我希望我没有错过任何明显的东西,但我一直在玩F#表达式,我想动态评估引用的表达式。例如,我想写这样的东西:

let x = <@ 2 * 5 @>
let y = transform x // replaces op_Multiply with op_Addition, or <@ 2 + 5 @>
let z = eval y // dynamically evaluates y, returns 7

是否有内置的F#方法可以评估引用的表达式,还是我必须自己编写?

5 个答案:

答案 0 :(得分:16)

我已经在Unquote中实现了基于反射的引用评估程序(这是2.0.0版本的新功能)。

> #r @"..\packages\Unquote.2.2.2\lib\net40\Unquote.dll"

--> Referenced '..\packages\Unquote.2.2.2\lib\net40\Unquote.dll'

> Swensen.Unquote.Operators.eval <@ sprintf "%A" (1,2) @>;;
val it : string = "(1, 2)"

我测得它比PowerPack评估员快50倍。当然,这将因情况而异。但是Unquote在解释表达式时通常比PowerPack更快。

它还支持比PowerPack的求值程序更多的表达式,包括VarSet,PropertySet,FieldSet,WhileLoop,ForIntegerRangeLoop和Quote。实际上,Unquote的评估程序支持所有引用表达式,除了 NewDelegate,AddressSet和AddressOf,我计划最终支持它们。

答案 1 :(得分:9)

不,没有内置的方法来编译F#引用。使用PowerPack LINQ,您可以将一些引用转换为.NET System.Linq.Expressions.Expression,并使用它来编译它们。

进行了引用以允许其他代码解释,例如定位SQL或GPU卡。

然而,在hubfs上的帖子中,有人暗示这是一个常见的请求,我们会对此进行审查。

答案 2 :(得分:8)

您可以使用Eval DLL提供的FSharp.PowerPack.Linq扩展成员评估F#引用,如下所示:

#r "FSharp.PowerPack.Linq.dll"

open Linq.QuotationEvaluation
let f = <@2 + 3@>
f.Eval()

请注意,您必须open Linq.QuotationEvaluation命名空间才能使此扩展成员可用。

还有一个Compile扩展成员返回暂停,但似乎无法提高性能。

答案 3 :(得分:6)

2016年更新

现在可以在NuGet包Evaluate

中找到FSharp.Quotations.Evaluator扩展方法
#r "../packages/FSharp.Quotations.Evaluator.1.0.7/lib/net40/FSharp.Quotations.Evaluator.dll"

open FSharp.Quotations.Evaluator

let f = <@ 2 + 3 @>
f.Evaluate()

答案 4 :(得分:0)

我认为引文有一个.eval() - 方法。