gpt4 book ai didi

reflection - 这是一个 F# 引用错误吗?

转载 作者:行者123 更新时间:2023-12-04 19:21:38 26 4
gpt4 key购买 nike

[<ReflectedDefinition>]
let rec x = (fun() -> x + "abc") ()

具有上述递归值的示例代码会产生以下 F# 编译器错误:

error FS0432: [<ReflectedDefinition>] terms cannot contain uses of the prefix splice operator '%'



我在上面的代码中看不到任何切片运算符的用法,看起来像一个错误...... :)

看起来这是通过 ReflectedDefinitionAttribute 引用的问题。只有,正常的报价效果很好:
let quotation =
<@ let rec x = (fun() -> x + "abc") () in x @>

使用隐藏的 Lazy.create 产生预期结果和 Lazy.force用途:
val quotation : Quotations.Expr<string> =
LetRecursive
([(x, Lambda (unitVar,
Application
(Lambda (unitVar0,
Call (None,
String op_Addition[String,String,String](String, String),
[Call (None,
String Force[String](Lazy`1[System.String]), // `
[x]), Value ("abc")])),
Value (<null>)))),
(x, Call (None, Lazy`1[String] Create[String](FSharpFunc`2[Unit,String]), [x])),
(x, Call (None, String Force[String](Lazy`1[String]), [x]))], x) // `

所以问题是:这是否是 F# 编译器错误?

最佳答案

我认为这可能是由 F# 中递归值的处理引起的。作为一种解决方法,您可以将递归引用转换为参数:

[<ReflectedDefinition>] 
let foo x = (fun() -> x + "abc") ()

// To construct the recursive value, you'd write:
let rec x = foo x

最后一行当然是无效的(就像您的原始代码一样),因为您正在创建一个立即递归引用,但它应该给您一个想法 - 实际上,您可能会附上 x在 lambda 函数中。

编辑 最初,我认为问题可能如下,但我现在不确定(见评论)。

对我来说,它看起来更像是一个(可能已知的)限制,而不是一个意外的错误。您编写的代码的两个版本之间有一个重要区别 - 在第一种情况下,您绑定(bind)了一个名为 x 的公共(public)值(对 .NET 可见)。而在第二种情况下, x只是一个仅在引用中使用的符号。

必须存储在程序集元数据中的报价如下所示:
let rec x = <@ (fun() -> %x + "abc") () @>

正文被引用,但 x不是带引号的符号,所以需要将它拼接到引号中(即会被求值,结果会被用在它的位置上)。请注意,此代码将失败,因为您正在声明一个带有立即引用的递归值 - x需要作为其定义的一部分进行评估,因此这是行不通的。

但是,我认为 %不能出现在 ReflectedDefinition引用(也就是说,您不能将上述内容存储在元数据中),因为它涉及一些运行时方面 - 您需要评估 x加载元数据时。

关于reflection - 这是一个 F# 引用错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2938652/

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