引用时
<@ 1 + 1 @>
Run Code Online (Sandbox Code Playgroud)
我想要"1 + 1"
代替
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
我已经实现了一个引用反编译器作为更大的开源项目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))"
Run Code Online (Sandbox Code Playgroud)
@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))))"
Run Code Online (Sandbox Code Playgroud)
中缀和前缀运算符并不太难(正如你在第一个例子中看到的那样),但是新行和缩进等源代码结构是一个有趣的话题(尽管我认为并不十分困难).但是,对于Unquote的要求,单行非轻量语法就足够了.