In C# I would implement Equals
for a class with structural equality like this:
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
var other = obj as MyType;
if (other != null)
{
return someField == other.someField &&
someOtherField == other.someOtherField;
}
return false;
}
In F# we have records for this, but if we want to use inheritance a type
must be implemented.
What is the equivalent Equals
implementation in F#?
A great way to use Structural Equation Models is to provide multiple hypothetical models, estimate each of them, and then analyze the differences between them to work towards a better and better model. There are different types of Structural Equation Models.
The equals method implements an equivalence relation on non-null object references: It is reflexive: for any non-null reference value x, x.equals (x) should return true. It is symmetric: for any non-null reference values x and y, x.equals (y) should return true if and only if y.equals (x) returns true.
Of course, this means extra coding, the risk of accidentally using comparison or equality fields inconsistently, as well as not explicitly stating in your domain what the comparison fields really are. F# allows you to override the equality checking in a few ways that you should take care of - in other words, whenever you do a .Equals or a = check.
For a class Person with string fields firstName and lastName, this would be a common variant to implement equals: Let’s go through it one by one. It is very important that equals takes an Object! Otherwise, unexpected behavior occurs. For example, assume that we would implement equals (Person) like so: What happens in a simple example?
As mentioned in the comments, you just need to override Equals
. The compiler will also tell you that it is a good idea to override GetHashCode
.
One neat trick is that you can just take all the relevant fields of your class, create tuples with them and then compare the tuples (or take hash code of the tuple). This makes the implementation much easier than if you were doing this by hand:
type Person(name:string, age:int) =
member x.Name = name
member x.Age = age
override x.GetHashCode() =
hash (name, age)
override x.Equals(b) =
match b with
| :? Person as p -> (name, age) = (p.Name, p.Age)
| _ -> false
Person("Joe", 42) = Person("Joe", 42)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With