问题
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
Equals
is 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