引用时
<@ 1 + 1 @>
我想要“1 + 1”
而不是
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
答案 0 :(得分:6)
你必须自己写。请参阅F# quotations visualizer代码作为转换引文抽象语法树的指南。
答案 1 :(得分:5)
我已经将引用反编译器实现为更大的开源项目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#Quotations反编译成人类可读形式时面临的许多挑战是正确的。但是从我到目前为止的工作中,我认为 可以编写引用反编译器,它可以生成正确的 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的要求,单行非轻量语法就足够了。
答案 2 :(得分:0)
没有,除了非常简单的情况外,它并不那么容易。例如,主要问题之一是匹配构造。它是一大堆if和switch语句的语法糖(尝试打印带匹配的引号,你会看到)。另外一个是计算表达式,但我想你最初可以跳过这些表达式。
然后有一个你需要解决的模糊性的兔子洞,像管道操作符这样的约定开始一个新的行,让我们开始一个新行,缩进,中缀,前缀,特殊情况如(::)操作员等等。
总而言之,可行,但不是微不足道的。有点像反编译。