У меня есть этот бит кода:
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
и .<1>.
(в обозначении MetaOcaml):
.<(fun x_1 -> (fun x_2 -> (fun x_3 -> x_3 + (x_2 + (x_1 + 1))) 1) 2) 3>.
Как вы можете видеть, x
´ заменяется на 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 <@ 1 @>).Eval() = 4
, где выше дает h 3 1 = 7
.И здесь я хочу, чтобы ответом стал 7
.