Я хочу сделать hashset
из (int*int)[]
, так как следующКак сделать IEqualityComparer для (int * int) [] выполнения структурного сравнения?
let mySet = new HashSet<_>()
, потому что я думал, компаратор по умолчанию для array
и tuple
является HashIdentity.Structural
, он будет автоматически удовлетворять свои потребности.
Однако это не работает. Вот мой эксперимент:
let mySet = new HashSet<_>()
let a = [|1;2|]
let b = [|1;2|]
let c = compare a b
mySet.Add(a)
mySet.Add(b)
val a : int [] = [|1; 2|]
val b : int [] = [|1; 2|]
val c : int = 0
val it : HashSet<int []> = seq [[|1; 2|]; [|1; 2|]]
let mySet = new HashSet<_>()
let a = [1;2]
let b = [1;2]
let c = compare a b
mySet.Add(a)
mySet.Add(b)
val a : int list = [1; 2]
val b : int list = [1; 2]
val c : int = 0
val it : HashSet<int list> = seq [[1; 2]]
Как мы можем видеть, что по умолчанию IEqualityComparer
для массива не HashIdentity.Structural
, но список есть. Однако по умолчанию IComparer
является структурным для обоих из них.
Это немного странно, по какой-либо причине? Также, как сделать IEqualityComparer
для моего hashset, используя структурное сравнение по умолчанию tuple
и array
.
Я знаю, как это сделать вручную на C#, но так как я только начал изучать F #, может ли кто-нибудь помочь?
Следующий код мои усилия:
let a = [|(1,2);(2,3)|]
let b = [|(1,2);(2,3)|]
type MyEqualityComparer() =
interface IEqualityComparer<(int*int)[]> with
member this.Equals (a,b) = (Array.forall2 (=) a b)
member this.GetHashCode (a) = hash (a |> Array.map hash)