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 Categorys 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