Кавычки представляют код F #, который был цитирован синтаксически .Это означает, что если вы напишите что-то вроде <@ x @>
, цитата будет содержать только Value
регистр, указывающий, что вы цитировали что-то, имеющее указанное значение.(Переменные автоматически заменяются значениями, если переменная определена вне кавычек).
Вы можете получить только цитату кода, который был явно заключен в кавычки с использованием <@ .. @>
, или функции, помеченной как ReflectedDefinition
и упоминается имя в кавычках (например, <@ add @>
, но не, например, let f = add in <@ f @>
).
Чтобы иметь возможность делать то, что предлагает ваш фрагмент кода, вам также нужно хранить цитаты в вашем FuncType
(чтобы лямбда-функция, которую вы пишете, также заключалась в кавычки и вы могли получить ее тело).Примерно так:
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"
Это должно работать и для функций, помеченных как ReflectedDefinition
.Чтобы извлечь тело функции, вам нужно добавить что-то вроде (вам нужно заменить аргументы функции на параметры, но это должно дать вам некоторое представление):
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"