F#:将接口(如 IComparable)添加到现有类型(例如来自 Fare 等库)
F#: Adding an interface (like IComparable) to an existing type (e.g. from a library like Fare)
Context:我在 F# 中使用 .net/c#-library Fare,我尝试使用例如Map.ofSeq
。这失败了,因为 Fare.State
不支持比较,因为它没有实现 System.IComprable
接口(FS0001)。
出于天真,我尝试像这样添加 interface IComparable
:
type Fare.State with
interface IComparable<Fare.State> with
member this.CompareTo obj =
match box obj with
| :? Fare.State as other -> this.Id.CompareTo other.Id
| _ -> invalidArg "obj" "not a State"
然而,这是不可能的,因为 F# 要求应在类型的初始声明 (FS0909) 上声明已实现的接口。
我想到了以下解决方法:
- 引入一个包含
Fare.State
作为其唯一属性并实现 IComparable
的包装器类型
- 存储 ID 而不是实际的 ID
Fare.State
并使用 Map 转换为需要的实际状态
- 使用一些技巧将
interface IComparable
添加到现有类型。
如果第三个选项不可能,哪个选项最合适?还有其他选择吗?
虽然 State
类型确实实现了(泛型)IComparable<'T>
,但 F# 在比较约束中寻找的是(非泛型)IComparable
。前者不是后者的子类型这一事实似乎是一个可悲的设计选择,但它会保留下来。
你的解决方法 1 和 2 对我来说很有意义。从设计的角度来看,我更喜欢 State
周围的简单记录包装器。但是,如果 ID 是唯一的,则可以考虑使用其他解决方法,如果有点笨拙的话。
Context:我在 F# 中使用 .net/c#-library Fare,我尝试使用例如Map.ofSeq
。这失败了,因为 Fare.State
不支持比较,因为它没有实现 System.IComprable
接口(FS0001)。
出于天真,我尝试像这样添加 interface IComparable
:
type Fare.State with
interface IComparable<Fare.State> with
member this.CompareTo obj =
match box obj with
| :? Fare.State as other -> this.Id.CompareTo other.Id
| _ -> invalidArg "obj" "not a State"
然而,这是不可能的,因为 F# 要求应在类型的初始声明 (FS0909) 上声明已实现的接口。
我想到了以下解决方法:
- 引入一个包含
Fare.State
作为其唯一属性并实现IComparable
的包装器类型
- 存储 ID 而不是实际的 ID
Fare.State
并使用 Map 转换为需要的实际状态 - 使用一些技巧将
interface IComparable
添加到现有类型。
如果第三个选项不可能,哪个选项最合适?还有其他选择吗?
虽然 State
类型确实实现了(泛型)IComparable<'T>
,但 F# 在比较约束中寻找的是(非泛型)IComparable
。前者不是后者的子类型这一事实似乎是一个可悲的设计选择,但它会保留下来。
你的解决方法 1 和 2 对我来说很有意义。从设计的角度来看,我更喜欢 State
周围的简单记录包装器。但是,如果 ID 是唯一的,则可以考虑使用其他解决方法,如果有点笨拙的话。