具有静态解析类型参数的类型的自定义相等性
Custom equality of types with statically resolved type parameters
如何在具有静态解析类型参数的 F# 类型中实现自定义相等方法?
我试过这样做:
[<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
我在 this.Equals
行收到以下错误:
This member, function or value declaration may not be declared 'inline'
这是为什么?是因为 Equals
是覆盖吗?如果是这样,是否有任何方法可以实现自定义相等性,或者我是否被迫使用 IEqualityComparer
?
Why is that? Is it because the Equals
is an override?
是的,是的。 class 的 inline
方法不是 class 的 实际 方法。相反,在某处对该方法的每次调用都将被解释为它的实现(非常类似于 C++)。由于您正在重写 Equals
方法,它是一个实际方法(来自 Object
class),因此您无法使其成为 inline
.
If that's the case, is there any way at all to implement the custom equality?
您可以从类型中提取具体乘法,这样您就不会被迫为Equals
方法使用inline
:
[<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
如何在具有静态解析类型参数的 F# 类型中实现自定义相等方法?
我试过这样做:
[<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
我在 this.Equals
行收到以下错误:
This member, function or value declaration may not be declared 'inline'
这是为什么?是因为 Equals
是覆盖吗?如果是这样,是否有任何方法可以实现自定义相等性,或者我是否被迫使用 IEqualityComparer
?
Why is that? Is it because the
Equals
is an override?
是的,是的。 class 的 inline
方法不是 class 的 实际 方法。相反,在某处对该方法的每次调用都将被解释为它的实现(非常类似于 C++)。由于您正在重写 Equals
方法,它是一个实际方法(来自 Object
class),因此您无法使其成为 inline
.
If that's the case, is there any way at all to implement the custom equality?
您可以从类型中提取具体乘法,这样您就不会被迫为Equals
方法使用inline
:
[<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