gpt4 book ai didi

F# 引用 - 遍历由值表示的函数调用

转载 作者:行者123 更新时间:2023-12-05 00:05:01 26 4
gpt4 key购买 nike

我花了几个小时试图掌握 F# Quotations,但我遇到了一些障碍。我的要求是从可区分的联合类型中取出简单的函数(只是整数、+、-、/、*)并生成一个表达式树,最终将用于生成 C 代码。我知道使用带有“直接”功能的引用是可能的。

我的问题是表达式树似乎以“值”结尾,我不知道如何遍历该值。

我的问题是
在这种情况下这是否真的可能?或者有没有其他值得考虑的方法。

type FuncType = 
| A of (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"

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

最佳答案

引用表示在语法上引用的 F# 代码。这意味着如果你写类似 <@ x @> 的东西, 报价将只包含 Value case 指定您引用了具有指定值的内容。 (如果变量是在引用之外定义的,则变量会自动替换为值)。

您只能获取使用 <@ .. @> 显式引用的代码的引用。或标记为 ReflectedDefinition 的函数并且在引号中按名称引用(例如 <@ add @> 但不是例如 let f = add in <@ f @> )。

为了能够按照您的代码段的建议进行操作,您需要在 FuncType 中存储引用。也是(这样你写的 lambda 函数也被引用,你可以得到它的主体)。就像是:

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"

关于F# 引用 - 遍历由值表示的函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4944668/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com