I have a type for logging levels:
type LoggingLevel =
| Trace
| Debug
| Info
I would like to say that some logging levels are higher than others. For example, Trace
is higher than Info
.
So I implemented IComparable
like this:
[<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)
But when I try to use it, I get an error:
if a >= b
then
// ...
The type 'LoggingLevel' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
How have I gone wrong here?
I managed to get it working, but now the type definition is so verbose! There must be a better way...
[<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)
I would like to say that some logging levels are higher than others. For example,
Trace
is higher thanInfo
.
Do you need to use custom equality and custom comparison at all? F# has these built in for Discriminated Unions. You just need to write them in increasing order in the type definition:
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 ✔
More info: https://stackoverflow.com/a/52220335/1256041