Question

following prints "false"

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

printfn "%A" (e1 = e2) 

The reason is that Var nodes are compared by pointer reference and not by structural equality. Is there already implemented a way to compare quotations intuitively?

Was it helpful?

Solution

There are many reasons why comparing quotations does not "work" by default:

  • Quotations can contain references to values for which comparison may not be defined (e.g. if you create a quotation that captures some .NET object that does not support comparison).
  • Quotations contain information about the location in the source code - so your two quotations are different simply because they are on different lines!
  • There is a question whether you want to treat (fun x -> x) and (fun y -> y) as the same - logically, they are, but syntactically, they are not.

So, if you want to check whether quotations are equal, you'll just have to implement your own check. Something like this does the trick for the basic case you have in the example, but it does not handle all the cases:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top