generics - 具有静态解析类型参数的类型的自定义相等性

标签 generics types f# inline equality

如何使用静态解析的类型参数在 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?



是的。安 inline类的方法不是该类的实际方法。相反,在某处对该方法的每次调用都将被解释为它的实现(与 C++ 非常相似)。由于您要覆盖 Equals方法是一个实际的方法(来自 Object 类),你不能让它 inline .

If that's the case, is there any way at all to implement the custom equality?



您可以从类型中提取具体的乘法,因此您不会被迫使用 inlineEquals方法:
[<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

关于generics - 具有静态解析类型参数的类型的自定义相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56115210/

相关文章:

c# - 在实现该接口(interface)的类中强制执行数字类型的接口(interface)

types - 在 coq 中类型转换可转换类型

postgresql - 如何从 postgresql 函数返回表的不确定数字列?

F# 循环遍历函数列表,依次将每个函数应用于一个数字

algorithm - F#写红黑树的难点

java - 为什么不能将具有其他类型的实例分配给参数化变量?

.net - 使用 CType Int32?到 Int64? - System.InvalidCastException : Specified cast is not valid

java - 泛型类型作为构造函数参数

C 未知类型名称堆栈

enums - 从有区别的联合映射到枚举