我在運行時遇到了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的一部分。