在F#引用中插入变量值

时间:2014-03-31 13:06:50

标签: f# quotations

所以我有一个名为evalExpr的函数,它接受引号< @ ... @>作为参数它返回一个值。 例如,如果我写

let v = evalExpr <@ 22 + 2 * 22 + 45 @>

然后,v等于111。

现在,我想在引号内放置一个字符串变量而不是表达式,但是这样做,变量是引用的一部分,因此没有定义。

如何在F#中使用引号内的变量值?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

目前还不清楚你究竟要求的是什么,但也许这样的事情会有所帮助吗?

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 @>