所以我有一个名为 evalExpr 的函数,它接受引号 <@ ... @> 作为参数,并返回一个值。例如,如果我写
let v = evalExpr <@ 22 + 2 * 22 + 45 @>
那么,v 等于 111。
现在,我想在引号内放置一个字符串变量而不是表达式,但是这样做,变量是引号的一部分,因此没有定义。
如何在 F# 中的引号内使用变量值?
所以我有一个名为 evalExpr 的函数,它接受引号 <@ ... @> 作为参数,并返回一个值。例如,如果我写
let v = evalExpr <@ 22 + 2 * 22 + 45 @>
那么,v 等于 111。
现在,我想在引号内放置一个字符串变量而不是表达式,但是这样做,变量是引号的一部分,因此没有定义。
如何在 F# 中的引号内使用变量值?
Unquote具有一个运算符evalWith : Map<string,obj> -> Quotations.Expr<'a> -> 'a
,允许您使用提供变量值的环境映射来评估具有未绑定变量的合成报价。
首先,打开Swensen.Unquote
命名空间以使evalWith
操作符可用。
open Swensen.Unquote;;
接下来,构造一个表示x
类型变量的引号int
:
let xvar : Quotations.Expr<int> = Quotations.Expr.Var(new Quotations.Var("x", typeof<int>)) |> Quotations.Expr.Cast;;
接下来,构造一个带有xvar
拼接的引用:
let q = <@ %xvar + 10 @>;;
q
现在您可以使用提供的变量来评估您的报价,x
如下所示:
evalWith (Map.ofList [("x", box 2)]) q;;
答案是12
!
目前还不清楚你到底要什么,但也许这样的事情会有所帮助?
type Vars<'a> private () =
static let dict = System.Collections.Generic.Dictionary<string,Quotations.Var>()
static member Var(nm) =
match dict.TryGetValue nm with
| true, v -> v
| _ ->
let v = Quotations.Var(nm, typeof<'a>)
dict.[nm] <- v
v
[<GeneralizableValue>]
let x<'a> : Quotations.Expr<'a> = Quotations.Expr.Var(Vars<'a>.Var "x") |> Quotations.Expr.Cast
[<GeneralizableValue>]
let y<'a> : Quotations.Expr<'a> = Quotations.Expr.Var(Vars<'a>.Var "y") |> Quotations.Expr.Cast
let q1 = <@ %x + %y * (1 + %x) @>
let q2 = <@ "test" + %x @>