Skip to content

Instantly share code, notes, and snippets.

Created September 9, 2011 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/1207279 to your computer and use it in GitHub Desktop.
Save anonymous/1207279 to your computer and use it in GitHub Desktop.
open System
open System.Collections.Generic
// first arg is always 'this' so assuming that it cannot be null
let rec equals(a : 'T, b : obj) comparisons =
if obj.ReferenceEquals(a, b) then true
else
match b with
| null -> false
| (:? 'T as b) -> comparisons |> Seq.forall(fun c -> c a b)
| _ -> false
// get values and compares them using obj.Equals (deals with nulls in both positions then calls <first arg>.Equals(<second arg>))
let Eq f a b = obj.Equals(f a, f b)
// get values and compares them using IEqualityComparer
let (=>) f (c : IEqualityComparer<_>) a b = c.Equals(f a, f b)
type A(name) =
member __.Name = name
override this.Equals(that) =
equals (this, that) [
(fun x -> x.Name) => StringComparer.InvariantCultureIgnoreCase
]
type B(parent:A, name) =
member __.Parent = parent
member __.Name = name
override this.Equals(that) =
equals(this, that) [
Eq(fun x -> x.Parent)
(fun x -> x.Name) => StringComparer.InvariantCultureIgnoreCase
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment