#f#
#f#
Вопрос:
Возможно ли это как-то реализовать IComparable
для HashSet<'a>
? Причина этого в том, что у меня объявлена следующая запись:
[<StructuralComparison>]
type Category = {
mutable Id: string;
Name: string;
SavePath: string;
Tags: HashSet<Tag> }
and Tag = { Tag:string; }
Как вы можете видеть, тогда теги в Category
записи имеют тип HashSet<Tag>
— и для того, чтобы отобразить последовательность категорий на карту, мне нужно IComparable
как-то реализовать … иначе это просто приведет к:
Структура, запись или тип объединения ‘Category’ имеет атрибут ‘StructuralComparison’, но тип компонента ‘HashSet’ не удовлетворяет ‘сравнению’
Пожалуйста, обратите внимание, что я не могу использовать ничего другого, кроме a HashSet<'a>
, поскольку база данных, с которой я работаю, вообще не понимает никаких списков в формате fsharp.
Ответ №1:
Я предположу, что вы хотите сравнить и приравнять Category
s, принимая во внимание только Id
, Name
и SavePath
(в таком порядке), заставляя запись вести себя так, как будто Tags
ее нет:
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; }
Однако, если вместо этого вы хотите сравнить по Name
и приравнять по Id
, тогда рассмотрите следующее:
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; }
Ответ №2:
Смотрите
https://learn.microsoft.com/en-gb/archive/blogs/dsyme/equality-and-comparison-constraints-in-f
Вкратце, я думаю, вы хотите применить атрибуты CustomEquality
и CustomComparison
к этому типу, а затем реализовать его самостоятельно.