我有这段代码:
let rec h n z = if n = 0 then z
else <@ (fun x -> %(h (n - 1) <@ x + %z @>)) n @>
从http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf中的 MetaOcaml 示例转换而来
在论文中解释了上面的例子将产生以下参数3
和.<1>.
(在 MetaOcaml 表示法中):
.<(fun x_1 -> (fun x_2 -> (fun x_3 -> x_3 + (x_2 + (x_1 + 1))) 1) 2) 3>.
正如您所看到的,x
's 被替换为等x_1
,x_2
因为x
否则只会指代x
最里面的fun
。
但在 F# 中这是不允许的。我收到编译时错误:“变量 'x' 绑定在引号中,但用作拼接表达式的一部分。这是不允许的,因为它可能会超出其范围。” 所以问题是:如何改变它以便编译并具有与 MetaOcaml 输出相同的语义?
更新评论:我使用 PowerPack 来实际评估报价。但我认为这与它没有任何关系,因为错误发生在编译时。到目前为止 QuotationEvaluation 有效。但是,我知道这可能不是最有效的实现。
更新 Tomas 的回答:
我真的不希望x
成为全球性的,或逃避范围。但我想要的是相当于
let rec h n z = if n = 0 then z
else (fun x -> (h (n - 1) (x + z))) n
带引号。您的回答给出(h 3 <@ 1 @>).Eval() = 4
了上述产生的位置h 3 1 = 7
。在这里,我想7
成为答案。