问题
How to implement custom equality methods in F# types with statically resolved type parameters?
I've tried doing it this way:
[<CustomEqualityAttribute>]
type Fraction< ^a when ^a: equality and ^a : (static member (*): ^a * ^a -> ^a) > (nominator: ^a, denominator: ^a) =
member inline this.Nominator = nominator
member inline this.Denominator = denominator
member inline this.IsEqualTo(other: Fraction< ^a >) = this.Nominator * other.Denominator = other.Nominator * this.Denominator
override inline this.Equals(other: obj) =
match obj with
| :? Fraction< ^a > as f -> this.IsEqualTo(f)
| _ -> false
I get the following error on the this.Equals line:
This member, function or value declaration may not be declared 'inline'
Why is that? Is it because the Equals is an override? If that's the case, is there any way at all to implement the custom equality or am I forced to use an IEqualityComparer?
回答1:
Why is that? Is it because the
Equalsis an override?
Yes, it is. An inline method of a class is not an actual method of the class. Rather, every call to that method at somewhere will be interpreted as its implementation (very similar to C++). Since you are overriding the Equals method which is an actual method (from the Object class), you cannot make it inline.
If that's the case, is there any way at all to implement the custom equality?
You can extract the concrete multiplication out of the type, so you won't be forced to use inline for the Equals method:
[<CustomEquality; NoComparison>]
type Frac<'T when 'T : equality> = private {
nominator : 'T
denominator : 'T
mult : 'T -> 'T -> 'T
} with
member x.Nominator = x.nominator
member x.Denominator = x.denominator
override x.Equals other =
match other with
| :? Frac<'T> as o ->
let ( * ) = x.mult in x.nominator * o.denominator = o.nominator * x.denominator
| _ -> false
static member inline Create x y = { nominator = x; denominator = y; mult = ( * ) }
// Test
Frac.Create 1 2 = Frac.Create 3 6 // true
Frac.Create 1.0 2.0 = Frac.Create 3.0 7.0 // false
Frac.Create 1 2 = Frac.Create 3.0 6.0 // compile error
来源:https://stackoverflow.com/questions/56115210/custom-equality-of-types-with-statically-resolved-type-parameters