是否有任何内置函数用于人类可读的F#报价?

时间:2009-09-19 17:00:25

标签: f# quotations

引用时

<@ 1 + 1 @>

我想要“1 + 1”

而不是

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

3 个答案:

答案 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语句的语法糖(尝试打印带匹配的引号,你会看到)。另外一个是计算表达式,但我想你最初可以跳过这些表达式。

然后有一个你需要解决的模糊性的兔子洞,像管道操作符这样的约定开始一个新的行,让我们开始一个新行,缩进,中缀,前缀,特殊情况如(::)操作员等等。

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

相关问题