我希望我没有错过任何明显的东西,但我一直在玩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#方法可以评估引用的表达式,还是我必须自己编写?
答案 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()
- 方法。