F# Quotations - traversing into function calls represented by a Value -
i've spent few hours trying grips f# quotations, i've come across bit of road block. requirement take simple functions (just integers,+,-,/,*) out of discriminated union type , generate expression tree used generate c code. know possible using quotations 'direct' functions.
my problem expression tree seems terminate "value", , can't figure out how traverse value.
my questions whether possible in situation? or there other approaches worth considering.
type functype = | of (int -> int -> int) | b | c [<reflecteddefinition>] let add x y = x + y let myfunc1 = (fun x y -> x + y ) let myfunc2 = add let thefunc expr = match expr | a(x) -> <@ x @> | _ -> failwith "fail" printfn "%a" (thefunc myfunc1) // prints "value (<fun:myfunc1@14>)" printfn "%a" (thefunc myfunc2) // prints "value (<fun:myfunc2@15>)" printfn "%a" <@ fun x y -> x + y @> // generates usable expression tree
quotations represent f# code quoted syntactically. means if write <@ x @>
, quotation contain value
case specifying quoted has specified value. (variables automatically replaced values if variable defined outside of quotation).
you can quotation of code explicitly quoted using <@ .. @>
or of function marked reflecteddefinition
, referred name in quotation (e.g. <@ add @>
not example let f = add in <@ f @>
).
to able snippet suggests, you'll need store quotations in functype
(so lambda function write quoted , can body). like:
type functype = | of expr<int -> int -> int> | b | c [<reflecteddefinition>] let add x y = x + y let myfunc1 = <@ fun x y -> x + y @> let myfunc2 = <@ add @> let thefunc expr = match expr | a(x) -> x | _ -> failwith "fail"
this should work functions marked reflecteddefinition
too. extract body of function need add (you'll need substitute arguments of function parameters, should give idea):
match expr | lambdas(_, body) -> match body | call(_, mi, _) when expr.trygetreflecteddefinition(mi) <> none -> let func = expr.trygetreflecteddefinition(mi) match func | some(lambdas(_, body)) -> // 'body' quotation of body | _ -> failwith "not supported function" | _ -> failwith "not supported function" | _ -> failwith "not supported expression"
Comments
Post a Comment