我在运行时遇到了lambda函数的代码引用问题。下面是一个非常简单的例子来说明这一点。我已经给在运行时产生的错误(不编译时)每次尝试下:Code Quotations:如何在内部访问lambda函数的变量?
open FSharp.Quotations
// First Attempt
let exprFun (a:int) (b:int) :Expr<int> = <@ a+b @>
let q1:Expr<int->int->int> = <@ fun x y -> %(exprFun x y) @> // NB: need to pass around and access `x` & `y` within a nested quotation expression
// error: The variable 'x' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope.
// Second Attempt
let x = new Var("x", typeof<int>)
let xe = Expr.Cast<int> (Expr.Var(x))
let y = new Var("y", typeof<int>)
let ye = Expr.Cast<int> (Expr.Var(y))
let q2 = Expr.Cast< int->int->int > (Expr.Lambda(x, Expr.Lambda(y, <@ %(exprFun %xe %ye) @>)))
// System.InvalidOperationException: first class uses of '%' or '%%' are not permitted
我深知,这个例子并不需要将x & y variables
传递给exprFun
但在我的现实世界的例子,我需要这种行为,因为我将这些变量传递给一个复杂的递归函数,该函数将返回一个Code Quotation/Expression本身。
实际上,我的要求是exprFun
能够访问/操作这些变量,作为生成正在生成的lambda函数的rhs的Code Quotation的一部分。