希望我没有错过什么显而易见的东西,但我一直在尝试使用 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#方法可以评估引用表达式,还是我必须编写自己的方法?
希望我没有错过什么显而易见的东西,但我一直在尝试使用 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#方法可以评估引用表达式,还是我必须编写自己的方法?
作为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)"
没有内置的方法来编译F#引用。使用PowerPack LINQ,您可以将某些引用转换为.NET System.Linq.Expressions.Expression,并使用它们进行编译。
引用是为了允许对代码进行其他解释,例如针对SQL或GPU卡。
但是,在hubfs上的帖子中,暗示这是一个常见的请求,并且将会加以考虑。
FSharp.PowerPack.Linq
DLL 提供的 Eval
扩展成员来评估 F# 引用,具体操作如下:#r "FSharp.PowerPack.Linq.dll"
open Linq.QuotationEvaluation
let f = <@2 + 3@>
f.Eval()
Linq.QuotationEvaluation
命名空间才能使用此扩展成员。Compile
扩展成员返回悬挂,但似乎并不会提高性能。2016年更新
Evaluate
扩展方法现在可以在NuGet包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()
我认为引号已经有了一个.eval()
方法。
Eval
,但我会给你点赞。我不明白为什么你和我的答案都有三个未注释的踩... - J D
decompile
、reduce
、reduceAll
、eval
和unquote
。 - Stephen Swensen