Is it possible to somehow implement IComparable
for a HashSet<'a>
? The reason for this is that I have following record declared:
[<StructuralComparison>]
type Category = {
mutable Id: string;
Name: string;
SavePath: string;
Tags: HashSet<Tag> }
and Tag = { Tag:string; }
As you can see, then Tags in the Category
record is of type HashSet<Tag>
- and in order to map a sequence of Categories to a Map, I'll need to implement the IComparable
somehow... else it will just result in:
The struct, record or union type 'Category' has the 'StructuralComparison' attribute but the component type 'HashSet' does not satisfy the 'comparison'
Please note that I cant use anything else than a HashSet<'a>
since the database I'm working with dosent understand any fsharp-ish lists at all.
I'll assume you want to compare and equate Category
s by taking only Id
, Name
, and SavePath
into account (in that order), making the record behave as though Tags
wasn't present:
open System
open System.Collections.Generic
[<CustomComparison; CustomEquality>]
type Category =
{ mutable Id : string;
Name : string;
SavePath : string;
Tags : HashSet<Tag> }
member private this.Ident = this.Id, this.Name, this.SavePath
interface IComparable<Category> with
member this.CompareTo other =
compare this.Ident other.Ident
interface IComparable with
member this.CompareTo obj =
match obj with
| null -> 1
| :? Category as other -> (this :> IComparable<_>).CompareTo other
| _ -> invalidArg "obj" "not a Category"
interface IEquatable<Category> with
member this.Equals other =
this.Ident = other.Ident
override this.Equals obj =
match obj with
| :? Category as other -> (this :> IEquatable<_>).Equals other
| _ -> false
override this.GetHashCode () =
hash this.Ident
and Tag = { Tag : string; }
However, if instead you want to compare by Name
and equate by Id
then consider the following:
open System
open System.Collections.Generic
[<CustomComparison; CustomEquality>]
type Category =
{ mutable Id : string;
Name : string;
SavePath : string;
Tags : HashSet<Tag> }
interface IComparable<Category> with
member this.CompareTo { Name = name } =
this.Name.CompareTo name
interface IComparable with
member this.CompareTo obj =
match obj with
| null -> 1
| :? Category as other -> (this :> IComparable<_>).CompareTo other
| _ -> invalidArg "obj" "not a Category"
interface IEquatable<Category> with
member this.Equals { Id = id } =
this.Id = id
override this.Equals obj =
match obj with
| :? Category as other -> (this :> IEquatable<_>).Equals other
| _ -> false
override this.GetHashCode () =
this.Id.GetHashCode ()
and Tag = { Tag : string; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With