I\'ve spent a few hours trying to get to grips with F# Quotations, but I\'ve come across a bit of a road block. My requirement is to take simple functions (just integers,+,-
Quotations represent the F# code that was quoted syntactically. This means that if you write something like <@ x @>
, the quotation will contain just Value
case specifying that you quoted something which has the specified value. (Variables are automatically replaced with values if the variable is defined outside of the quotation).
You can only get quotation of code that was explicitly quoted using <@ .. @>
or of a function that was marked as ReflectedDefinition
and is referred to by name in a quotation (e.g. <@ add @>
but not for example let f = add in <@ f @>
).
To be able to do what your snippet suggests, you'll need to store quotations in your FuncType
too (so that the lambda function that you write is also quoted and you can get its body). Something like:
type FuncType =
| A of Expr<int -> int -> int>
| B | C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A <@ fun x y -> x + y @>
let myFunc2 = A <@ add @>
let thefunc expr =
match expr with
| A(x) -> x
| _ -> failwith "fail"
This should work for functions marked as ReflectedDefinition
too. To extract the body of the function you need to add something like (you'll need to substitute arguments of the function for parameters, but this should give you some idea):
match expr with
| Lambdas(_, body) ->
match body with
| Call(_, mi, _) when Expr.TryGetReflectedDefinition(mi) <> None ->
let func = Expr.TryGetReflectedDefinition(mi)
match func with
| Some(Lambdas(_, body)) ->
// 'body' is the quotation of the body
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported expression"