Different expressions are generated for "roughly" the same code quote

the following type is specified

type Foo = { foo: string; bar: int };;

and the following code quote

<@fun v x -> { x with foo = v; bar = 99 } @>;;

this will lead to

val it : Quotations.Expr<(string -> Foo -> Foo)> =
    Lambda (v, Lambda (x, NewRecord (Foo, v, Value (99))))

Expected. Also the following code quote

<@fun v x -> { x with bar = v;foo = "foo" } @>;;

gives the expected result.

val it : Quotations.Expr<(int -> Foo -> Foo)> =
    Lambda (v, Lambda (x, NewRecord (Foo, Value ("foo"), v)))

However, this (reordering and assigning a value to the second field)

<@fun v x -> { x with bar = 66;foo = v } @>;;

gives

val it : Quotations.Expr<(string -> Foo -> Foo)> =
    Lambda (v, Lambda (x, Let (bar, Value (66), NewRecord (Foo, v, bar))))

a let. But not in the code let. Why is this?

+4
source share
2 answers

Quotations ensure that they will generate expressions with the correct behavior, and not with a specific form.

For example, a quote <@@ 1 = 2 || 2 = 3 @@>will generate an expression containing an operator if(i.e. if 1 = 2 then true else 2 = 3).

- , : https://github.com/mavnn/Algebra.Boolean/blob/master/Algebra.Boolean/Transforms.fs

, unbind .

let unbind quote =
    let rec findLet q =
        match q with
        | Let (var, value, body) ->
            findLet (replaceVar var.Name value body)
        | ShapeLambda (v, e) ->
            Expr.Lambda(v, findLet e)
        | ShapeVar v ->
            Expr.Var v
        | ShapeCombination (o, es) ->
            RebuildShapeCombination(o, es |> List.map findLet)
    and replaceVar name value q =
        match q with
        | Let (v, e, e') ->
            if v.Name = name then
                findLet (Expr.Let(v, e, e'))
            else
                Expr.Let(v, replaceVar name value e, replaceVar name value e')
        | ShapeLambda (v, e) ->
            Expr.Lambda(v, replaceVar name value e)
        | ShapeVar v ->
            if v.Name = name then
                value
            else
                Expr.Var v
        | ShapeCombination (o, es) ->
            RebuildShapeCombination(o, es |> List.map (replaceVar name value))
    findLet quote

, ? , !

+4

, , , with . , v , , . , let, .

F #.

- , , . , , , ,

+4

Source: https://habr.com/ru/post/1652337/


All Articles