F#比较报价

Liv*_*viu 5 f#

以下打印"假"

let e1 = <@@ let d = 1 in d+1 @@>
let e2 = <@@ let d = 1 in d+1 @@>

printfn "%A" (e1 = e2) 
Run Code Online (Sandbox Code Playgroud)

原因是Var节点通过指针引用进行比较,而不是通过结构相等进行比较.是否已经实现了直观地比较报价的方法?

Tom*_*cek 8

有很多原因可以解释为什么默认情况下比较报价"不起作用":

  • 引号可以包含对可能未定义比较的值的引用(例如,如果您创建一个引用来捕获某些不支持比较的.NET对象).
  • 报价包含有关源代码中位置的信息 - 因此您的两个报价不同仅仅因为它们位于不同的行上!
  • 有一个问题,你是否想要对待(fun x -> x)(fun y -> y)相同 - 从逻辑上讲,它们是,但在语法上,它们不是.

因此,如果您想检查报价是否相等,您只需要实施自己的检查.像这样的东西可以解释你在示例中的基本情况,但它不能处理所有情况:

open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

let rec equal = function
  | Let(v1, ea1, eb1), Let(v2, ea2, eb2) -> 
      v1.Name = v2.Name && equal (ea1, ea2) && equal (eb1, eb2)
  | Var(v1), Var(v2) -> v1.Name = v2.Name
  | Lambda(v1, e1), Lambda(v2, e2) -> v1.Name = v2.Name && equal (e1, e2)
  | Call(None, m1, es1), Call(None, m2, es2) -> 
      m1 = m2 && (List.zip es1 es2 |> List.forall equal)
  | Value(v1), Value(v2) -> v1 = v2
  | _ -> false
Run Code Online (Sandbox Code Playgroud)