F# 内置的<&燃气轮机;比较;不';“我不能和”一起工作;i可比较<;T>&引用;?

F# 内置的<&燃气轮机;比较;不';“我不能和”一起工作;i可比较<;T>&引用;?,f#,comparison,F#,Comparison,我有一个有区别的并集,我希望使用内置操作符,比如0 |A,->1 |_u,A->-1 | _, _ -> 0 我知道我可以使用IComparable,但是我必须进行null检查,更糟糕的是,我必须像(SymbolType)y那样强制转换它,我认为这将非常耗时。您可以使用薄包装实现所需的方法: [<CustomComparison>] [<CustomEquality>] type SymbolType = | A | B | C |

我有一个有区别的并集,我希望使用内置操作符,比如

[<CustomComparison>]
type SymbolType = 
    | A
    | B
    | C
    | D

    interface IComparable<SymbolType> with
        member x.CompareTo y =
            match x, y with
            | A, A-> 0
            | A, _ -> 1
            | _, A-> -1
            | _, _ -> 0
[]
类型SymbolType=
|A
|B
|C
|D
接口i可与
成员x.CompareTo y=
将x,y与
|A,A->0
|A,->1
|_u,A->-1
| _, _ -> 0

我知道我可以使用
IComparable
,但是我必须进行
null
检查,更糟糕的是,我必须像
(SymbolType)y
那样强制转换它,我认为这将非常耗时。

您可以使用薄包装实现所需的方法:

[<CustomComparison>] 
[<CustomEquality>] 
type SymbolType = 
    | A
    | B
    | C
    | D
    override x.Equals y =
       match y with
       | :? SymbolType as t -> (((x :> IComparable<_>).CompareTo) t)=0
       | _ -> false
    interface IComparable with
        member x.CompareTo y =
            match y with
            | :? SymbolType as t -> ((x :> IComparable<_>).CompareTo) t
            | _ -> failwith "bad comparison"
    interface IComparable<SymbolType> with
        member x.CompareTo y =
            match x, y with
            | A, A-> 0
            | A, _ -> 1
            | _, A-> -1
            | _, _ -> 0
[]
[] 
类型SymbolType=
|A
|B
|C
|D
覆盖x等于y=
匹配
| :? 符号类型为t->(((x:>i可比较).CompareTo)t)=0
|_u->false
接口i可与
成员x.CompareTo y=
匹配
| :? 符号类型为t->((x:>i可比较)。比较为)t
|_u->failwith“糟糕的比较”
接口i可与
成员x.CompareTo y=
将x,y与
|A,A->0
|A,->1
|_u,A->-1
| _, _ -> 0

这种方法可以避免重复键入。

您只需使用精简包装器实现所需的方法即可:

[<CustomComparison>] 
[<CustomEquality>] 
type SymbolType = 
    | A
    | B
    | C
    | D
    override x.Equals y =
       match y with
       | :? SymbolType as t -> (((x :> IComparable<_>).CompareTo) t)=0
       | _ -> false
    interface IComparable with
        member x.CompareTo y =
            match y with
            | :? SymbolType as t -> ((x :> IComparable<_>).CompareTo) t
            | _ -> failwith "bad comparison"
    interface IComparable<SymbolType> with
        member x.CompareTo y =
            match x, y with
            | A, A-> 0
            | A, _ -> 1
            | _, A-> -1
            | _, _ -> 0
[]
[] 
类型SymbolType=
|A
|B
|C
|D
覆盖x等于y=
匹配
| :? 符号类型为t->(((x:>i可比较).CompareTo)t)=0
|_u->false
接口i可与
成员x.CompareTo y=
匹配
| :? 符号类型为t->((x:>i可比较)。比较为)t
|_u->failwith“糟糕的比较”
接口i可与
成员x.CompareTo y=
将x,y与
|A,A->0
|A,->1
|_u,A->-1
| _, _ -> 0

这种方法可以避免任何重复的输入。

在CLR上,运算符是静态函数,因此不能在接口中定义它们。但是,如果将接口用作泛型函数的类型参数约束,也可以避免装箱

int Compare<T>(T lhs, T rhs) where T : IComparable<T>
{
  return lhs.CompareTo(rhs) // no boxing
}
int比较(T lhs,T rhs),其中T:i可比较
{
返回lhs.CompareTo(rhs)//无装箱
}

很抱歉,我不熟悉F#,所以我用C#编写了这个示例。

在CLR上,运算符是静态函数,所以不能在接口中定义它们。但是,如果将接口用作泛型函数的类型参数约束,也可以避免装箱

int Compare<T>(T lhs, T rhs) where T : IComparable<T>
{
  return lhs.CompareTo(rhs) // no boxing
}
int比较(T lhs,T rhs),其中T:i可比较
{
返回lhs.CompareTo(rhs)//无装箱
}
很抱歉,我不熟悉F#,所以我用C#编写了这个示例。

您已经可以在类型上使用标准比较运算符了。内置实现使用单个案例的声明顺序,因此:

type SymbolType =  A | B | C | D 

// Behavior of built-in comparison
A < B   = true
D <= C  = false
max B D = D
类型SymbolType=A | B | C | D
//内置比较的行为
A
type SymbolType =  A | B | C | D 

// Behavior of built-in comparison
A < B   = true
D <= C  = false
max B D = D
类型SymbolType=A | B | C | D
//内置比较的行为
AD在F中的等价物是
let inline compare(a:'t:>IComparable)在F中的等价物是
let inline compare(a:'t:>icomparableetter你的代码,为什么我不能使用
a.CompareTo B
?它说
CompareTo
没有定义?@colinfang你必须写
(a:>IComparable)。CompareTo(B)
因为接口是隐式实现的(方法是隐藏的)。@TomasPetricek:你的意思是显式的吗?@Daniel是的,准确地说:-),接口是显式实现的!在你的代码之后,为什么我不能使用
A.CompareTo B
?它说
CompareTo
没有定义?@colinfang你必须写
(A:>IComparable)。与(B)
相比,因为接口是隐式实现的(方法是隐藏的)。@TomasPetricek:你的意思是显式实现的吗?@Daniel是的,确切地说:-),接口是显式实现的!可能重复的可能重复的