是否有任何内置函数可供人类可读的 F# 引用?

发布于 2024-08-05 19:56:52 字数 193 浏览 8 评论 0原文

引用时

<@ 1 + 1 @>

我想要“1 + 1”

而不是

"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32), [值 (1),值 (1)])"

When quoting

<@ 1 + 1 @>

I want "1 + 1"

instead of

"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光瘦了 2024-08-12 19:56:52

你必须自己写。请参阅 F# 引用可视化工具 代码作为转换引用抽象语法树的指南。

You'll have to write it yourself. See the F# quotations visualizer code as a guide for transforming the quotations abstract syntax tree.

绝不放开 2024-08-12 19:56:52

我已经实现了一个引文反编译器,作为大型开源项目 Unquote 的一部分。它可以将许多简单的 F# 引用表达式反编译为单行非轻语法字符串(有关反编译器功能的列表,请参阅项目主页)。例如,

> decompile <@ (11 + 3) / 2 = String.length ("hello world".Substring(4, 5)) @>;;
val it : string =
  "(11 + 3) / 2 = String.length ("hello world".Substring(4, 5))"

@Kurt Schelfthout 关于将 F# 引用反编译为人类可读形式时面临的许多挑战是正确的。但从我迄今为止的工作来看,我相信编写一个可以生成正确的 F# 代码的引用反编译器是可能的。以匹配表达式和计算表达式为例,Unquote 反编译器可以在以下简单情况下生成正确的 F# 代码:

> decompile <@ match true with | true -> "hi" | _ -> "bye"  @>;;
val it : string =
  "let matchValue = true in if matchValue then "hi" else "bye""

> decompile <@ seq {yield 1; yield 2}  @>;;
val it : string =
  "seq (Seq.delay (fun unitVar -> Seq.append (Seq.singleton 1) (Seq.delay (fun unitVar -> Seq.singleton 2))))"

中缀和前缀运算符不太难(如第一个示例中所示),但是源结构(例如换行和缩进)是一个有趣的主题(尽管我认为并不是非常困难)。然而,单行非轻量语法足以满足 Unquote 的要求。

I have implemented a quotation decompiler as part of a larger open source project Unquote. It can decompile many simple F# quoted expressions as single-line non-light syntax strings (see the project's home page for a list of decompiler features). For example,

> decompile <@ (11 + 3) / 2 = String.length ("hello world".Substring(4, 5)) @>;;
val it : string =
  "(11 + 3) / 2 = String.length ("hello world".Substring(4, 5))"

@Kurt Schelfthout is correct about the many challenges faced when decompiling F# Quotations into human readable form. But from my work so far, I believe that it is possible to write a quotation decompiler which can generate correct F# code. Take match expressions and computation expressions for example, the Unquote decompiler can produce correct F# code in the following simple cases:

> decompile <@ match true with | true -> "hi" | _ -> "bye"  @>;;
val it : string =
  "let matchValue = true in if matchValue then "hi" else "bye""

> decompile <@ seq {yield 1; yield 2}  @>;;
val it : string =
  "seq (Seq.delay (fun unitVar -> Seq.append (Seq.singleton 1) (Seq.delay (fun unitVar -> Seq.singleton 2))))"

Infix and prefix operators are not too hard (as you can see in the first example), but source structure such as new lines and indentation is an interesting topic (though not terribly difficult, I think). However, single-line non-light syntax is sufficient for Unquote's requirements.

此生挚爱伱 2024-08-12 19:56:52

没有,而且也不是那么容易,除非是非常简单的情况。例如,主要问题之一是匹配结构。它是一大堆 if 和 switch 语句的语法糖(尝试打印带有匹配项的引用,您会看到)。其中另一个重要因素是计算表达式,但我想您可以一开始就跳过它们。

然后,您必须解决一个充满歧义的兔子洞,其中包括诸如管道运算符开始新行、let 开始新行、缩进、中缀、前缀、特殊情况(例如 (::) 运算符等)的约定四。

总而言之,可行,但并非微不足道。有点像反编译。

There is none, and it's not quite that easy, except in very simple cases. One of the main problems, for example, is the match construct. It is syntactic sugar for a whole bunch of if and switch statements (try printing a quotation with a match in, you'll see). Another one of those biggies are computation expressions, but I guess you could skip those at first.

Then there is a the rabbit hole of ambiguities you'll have to resolve, with conventions like the pipe operator starts a new line, let starts a new line, indentation, infix, prefix, special cases like the (::) operator and so forth.

All in all, doable, but not trivial. Sort of like decompiling.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文