У меня есть этот фрагмент кода:
let rec h n z = if n = 0 then z
else <@ (fun x -> %(h (n - 1) <@ x + %z @>)) n @>
преобразован из примера MetaOcaml в http://www.cs.rice.edu/~taha/publications/journal/dspg04a. pdf
В документе объясняется, что приведенный выше пример даст следующие параметры с параметрами 3
и . .
(в нотации 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 работает. Однако я знаю, что это может быть не самая эффективная реализация.
Обновление ответа Томаса:
Я действительно не хочу, чтобы x
был глобальным или выходил из области видимости. Но мне нужен эквивалент
let rec h n z = if n = 0 then z
else (fun x -> (h (n - 1) (x + z))) n
с цитатами. Ваш ответ дает (h 3 ). Eval () = 4
, где приведенное выше дает h 3 1 = 7
. И здесь я хочу, чтобы 7
были ответом.