13

我希望我没有错过一些明显的东西,但我一直在玩 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# 方法,还是我必须自己编写?

4

5 回答 5

18

作为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 之外的所有引用表达式,我计划最终支持所有这些表达式。

于 2011-07-08T22:08:11.840 回答
9

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

引用是为了允许对代码进行其他解释,例如针对 SQL 或 GPU 卡。

然而,在 hubfs 上的帖子中,有人暗示这是一个常见的请求,将予以关注。

于 2009-05-11T18:34:32.293 回答
8

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

#r "FSharp.PowerPack.Linq.dll"

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

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

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

于 2011-07-09T09:17:34.177 回答
6

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()
于 2016-06-16T20:28:58.273 回答
-1

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

于 2009-05-11T18:34:14.743 回答