を逃れることができる私はこのコードのビットを持っている:紙でhttp://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdfF#の引用:変数がスコープ
にMetaOcaml例から変換
let rec h n z = if n = 0 then z
else <@ (fun x -> %(h (n - 1) <@ x + %z @>)) n @>
は、上記の例では、と次が得られることが説明されています(MetaOcaml表記)パラメータ3
と.<1>.
:
.<(fun x_1 -> (fun x_2 -> (fun x_3 -> x_3 + (x_2 + (x_1 + 1))) 1) 2) 3>.
あなたがを見ることができるようには、最も内側のx
のみを参照するため、は、x_1
、x_2
などで置き換えられます。fun
。
しかし、F#ではこれは許可されていません。コンパイル時エラーが発生する: "変数 'x'は引用符で囲まれていますが、スプライスされた式の一部として使用されます。スコープからエスケープする可能性があるため、これは許可されていません。だから問題は、これがどのように変更されてコンパイルされ、MetaOcamlの出力と同じセマンティックを持つことができるかということです。
コメントの更新:パワーパックを使用して、実際に見積もりを評価します。しかし、エラーはコンパイル時に発生するため、これと何も関係がないとは思わない。今のところ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
を答えたいと思っています。
MeyaOCamlは分かりませんが、実際のF#コードではラムダ引用の変数を使用しようとしているようです。引用は実際のF#コードではありません。そのため、それらを評価することはできません(完全ではないLINQエバリュエーターを除いて)。 –