(РЕДАКТИРОВАТЬ: CKoenig имеет хороший ответ.)
Хм, я тоже не сразу нашел способ сделать это.
Вот не типобезопасное решение, которое можетобеспечить сумасшедшее вдохновение для других.
open System.Collections.Generic
module Dict =
type Dictionary<'K, 'V> with
member this.Difference<'K2, 'T when 'K2 : equality>(that:Dictionary<'K2, 'T>) =
let dict = Dictionary<'K2,'V>()
for KeyValue(k, v) in this do
if not (that.ContainsKey(k |> box |> unbox)) then
dict.Add(k |> box |> unbox, v)
dict
open Dict
let d1 = Dictionary()
d1.Add(1, "foo")
d1.Add(2, "bar")
let d2 = Dictionary()
d2.Add(1, "cheese")
let show (d:Dictionary<_,_>) =
for (KeyValue(k,v)) in d do
printfn "%A: %A" k v
d1.Difference(d2) |> show
let d3 = Dictionary()
d3.Add(1, 42)
d1.Difference(d3) |> show
let d4 = Dictionary()
d4.Add("uh-oh", 42)
d1.Difference(d4) |> show // blows up at runtime
В целом может показаться, что невозможно объединить типы K
и K2
, не заставляя их иметь одинаковое ограничение равенства, хотя ...
(РЕДАКТИРОВАТЬ: кажется, что вызов в .NET, который не зависит от равенства является хорошим способом создать словарь в отсутствие дополнительного ограничения.)