Search code examples
f#quotations

Quotation Transformation in F# to another type


I have the following types:

type Foo = { Name : string}
type Bar = {Name : string}

And I have the following Quoted expression:

<@ fun (x : Foo) -> x.Name = "1" @>

Basically from this I would like to generate another quoted expression as:

<@ fun (x : Bar) -> x.Name = "1" @>

How can I do this?


Solution

  • OK I got the following solution :

    let subst expression newType =
        let newVar name = Var.Global(name,newType)
    
        let rec substituteExpr expression  =
            match expression with
            | Call(Some (ShapeVar var),mi,other) ->
              Expr.Call(Expr.Var(newVar var.Name), newType.GetMethod(mi.Name),other)
            | PropertyGet (Some (ShapeVar var)  ,pi, _) ->
                Expr.PropertyGet(Expr.Var( newVar var.Name), newType.GetProperty(pi.Name),[])
            | ShapeVar var -> Expr.Var <| newVar var.Name
            | ShapeLambda (var, expr) ->
                Expr.Lambda (newVar var.Name, substituteExpr expr)
            | ShapeCombination(shapeComboObject, exprList) ->
                RebuildShapeCombination(shapeComboObject, List.map substituteExpr exprList)
        substituteExpr expression
    

    then I can do

    let f = <@ fun (x : Foo) -> x.Name = "1" @>
    let transformed =  subst f typeof<Bar>
    let typedExpression: Expr<Bar -> bool> = downcast <@ %%transformed @>