我有一个日志记录级别类型:
type LoggingLevel =
| Trace
| Debug
| Info
我想说某些日志记录级别高于其他日志记录级别。例如,Trace
高于Info
。
所以我像这样实现IComparable
:
[<StructuralEqualityAttribute>]
[<CustomComparisonAttribute>]
type LoggingLevel =
| Trace
| Debug
| Info
interface IComparable<LoggingLevel> with
override this.CompareTo other =
let score x =
match x with
| Trace -> 0
| Debug -> 1
| Info -> 2
(score this) - (score other)
但是当我尝试使用它时,出现错误:
if a >= b
then
// ...
类型“ LoggingLevel”不支持“比较”约束。例如,它不支持“ System.IComparable”接口
我在这里怎么出错了?
我设法使其正常运行,但是现在类型定义太冗长了!一定有更好的方法...
[<CustomEquality>]
[<CustomComparisonAttribute>]
type LoggingLevel =
| Trace
| Debug
| Info
override this.Equals (obj) =
match obj with
| :? LoggingLevel as other ->
match (this, other) with
| (Trace, Trace) -> true
| (Debug, Debug) -> true
| (Info, Info) -> true
| _ -> false
| _ -> false
override this.GetHashCode () =
match this with
| Trace -> 0
| Debug -> 1
| Info -> 2
interface IComparable<LoggingLevel> with
member this.CompareTo (other : LoggingLevel) =
let score x =
match x with
| Trace -> 0
| Debug -> 1
| Info -> 2
(score this) - (score other)
interface IComparable with
override this.CompareTo other =
(this :> IComparable<LoggingLevel>).CompareTo (other :?> LoggingLevel)
答案 0 :(得分:1)
我认为您正在根据类型进行比较实施。以下为我编译:
[<CustomComparison>]
[<StructuralEquality>]
type LoggingLevel =
| Trace
| Debug
| Info
interface System.IComparable with
member this.CompareTo other =
0
// replace 0 with your comparison logic here
let a = Trace
let b = Debug
if Trace > Debug then printfn "here"
请注意,在这种情况下,other
的类型为obj
,您需要进行相应的装箱。由于这里的所有案例都是空的(即缺乏类型),这使所有的问题变得棘手。
我很想看到一个更完整的示例,您正在尝试使用此逻辑。我怀疑match
表达式可能会更好,并且可以删除此自定义比较。
也就是说,在不知道您确切的用例的情况下,这样的功能会更实用(也许更简单)吗?
type LoggingLevel = Trace | Debug | Info
module Logger =
let doSomeLogging logLevel =
match logLevel with
| Trace -> "trace"
| Debug -> "debug"
| Info -> "info"
let result = Logger.doSomeLogging Trace
答案 1 :(得分:1)
我想说某些日志记录级别高于其他日志记录级别。例如,
Trace
高于Info
。
您是否需要使用自定义相等性和自定义比较? F#已为歧视工会内置了这些功能。您只需要在类型定义中按升序编写它们:
type LoggingLevel =
| Info
| Debug
| Trace // Note the order here!
Trace > Info // true
let levels = [ Trace; Debug; Info; Trace; Debug; Info ]
levels |> List.sort
// [Info; Info; Debug; Debug; Trace; Trace]
// Comparison ✔
levels |> List.countBy id
// [(Trace, 2); (Debug, 2); (Info, 2)]
// Equality ✔