В дополнение к тому, что написал Брайан - я считаю, что кодирование доступа к глобальным let
связанным значениям также довольно стабильно, и они, вполне вероятно, будут продолжать кодироваться как PropGet
в будущем.
Это означает, что вы можете явно поддержать этот случай в вашем переводчике и добавить простой шаг предварительной обработки, чтобы получить значения этих свойств.Это можно сделать с помощью ExprShape
(что позволяет полностью пересмотреть цитату, используя только 4 случая).Это позволит вашему DSL также поддерживать общий случай.
Следующая функция перебирает цитаты и заменяет доступ к глобальным let
s их значениями:
open Microsoft.FSharp.Quotations
let rec expand e =
match e with
// Extract value of global 'let' bound symbols
| Patterns.PropertyGet(None, pi, []) ->
Expr.Value(pi.GetValue(null, [| |]), e.Type)
// standard recursive processing of quotations
| ExprShape.ShapeCombination(a, b) ->
ExprShape.RebuildShapeCombination(a, b |> List.map expand)
| ExprShape.ShapeLambda(v, b) -> Expr.Lambda(v, expand b)
| ExprShape.ShapeVar(v) -> Expr.Var(v)
Затем вы можете написатьследующее, чтобы получить цитату, содержащую значение вместо PropGet
:
let z = 5
let eOrig = <@ Seq.filter (fun p -> p = z) [ 1 .. 10 ]@>
let eNice = expand eOrig