4 people like it.
Like the snippet!
Dictionary with comparer as type parameter
Tired of confusing dictionary instances with different comparers (I am)? Stick it in the type, à la ocaml-core maps.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
open System
open System.Collections.Generic
type Dictionary<'TKey, 'TValue, 'TComparer when 'TKey : equality and 'TComparer :> IEqualityComparer<'TKey>>(comparer: 'TComparer) =
inherit Dictionary<'TKey, 'TValue>(comparer)
type DelegatingEqualityComparer<'a>(comparer: IEqualityComparer<'a>) =
interface IEqualityComparer<'a> with
member x.Equals(a,b) = comparer.Equals(a,b)
member x.GetHashCode a = comparer.GetHashCode a
type StringComparerInvariantCultureIgnoreCase() =
inherit DelegatingEqualityComparer<string>(StringComparer.InvariantCultureIgnoreCase)
type StringComparerInvariantCulture() =
inherit DelegatingEqualityComparer<string>(StringComparer.InvariantCulture)
let doSomething (data: Dictionary<string, _, StringComparerInvariantCultureIgnoreCase>) =
printfn "%A" data.["one"]
printfn "%A" data.["two"]
let data = Dictionary<_,int,_>(StringComparerInvariantCulture())
data.["One"] <- 1
data.["Two"] <- 2
doSomething data // doesn't compile, as the comparers are different!
let data2 = Dictionary<_,int,_>(StringComparerInvariantCultureIgnoreCase())
for KeyValue(k,v) in data do data2.Add(k,v)
doSomething data2 // works as expected
|
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Dictionary<'TKey,'TValue> =
new : unit -> Dictionary<'TKey, 'TValue> + 5 overloads
member Add : key:'TKey * value:'TValue -> unit
member Clear : unit -> unit
member Comparer : IEqualityComparer<'TKey>
member ContainsKey : key:'TKey -> bool
member ContainsValue : value:'TValue -> bool
member Count : int
member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
member Item : 'TKey -> 'TValue with get, set
...
nested type Enumerator
nested type KeyCollection
nested type ValueCollection
Full name: System.Collections.Generic.Dictionary<_,_>
--------------------
type Dictionary<'TKey,'TValue,'TComparer (requires equality and 'TComparer :> IEqualityComparer<'TKey>)> =
inherit Dictionary<'TKey,'TValue>
new : comparer:'TComparer -> Dictionary<'TKey,'TValue,'TComparer>
Full name: Script.Dictionary<_,_,_>
--------------------
Dictionary() : unit
Dictionary(capacity: int) : unit
Dictionary(comparer: IEqualityComparer<'TKey>) : unit
Dictionary(dictionary: IDictionary<'TKey,'TValue>) : unit
Dictionary(capacity: int, comparer: IEqualityComparer<'TKey>) : unit
Dictionary(dictionary: IDictionary<'TKey,'TValue>, comparer: IEqualityComparer<'TKey>) : unit
Dictionary(info: Runtime.Serialization.SerializationInfo, context: Runtime.Serialization.StreamingContext) : unit
--------------------
new : comparer:'TComparer -> Dictionary<'TKey,'TValue,'TComparer>
type IEqualityComparer<'T> =
member Equals : x:'T * y:'T -> bool
member GetHashCode : obj:'T -> int
Full name: System.Collections.Generic.IEqualityComparer<_>
val comparer : #IEqualityComparer<'TKey> (requires equality)
Multiple items
type DelegatingEqualityComparer<'a> =
interface IEqualityComparer<'a>
new : comparer:IEqualityComparer<'a> -> DelegatingEqualityComparer<'a>
Full name: Script.DelegatingEqualityComparer<_>
--------------------
new : comparer:IEqualityComparer<'a> -> DelegatingEqualityComparer<'a>
val comparer : IEqualityComparer<'a>
val x : DelegatingEqualityComparer<'a>
override DelegatingEqualityComparer.Equals : a:'a * b:'a -> bool
Full name: Script.DelegatingEqualityComparer`1.Equals
val a : 'a
val b : 'a
Object.Equals(obj: obj) : bool
IEqualityComparer.Equals(x: 'a, y: 'a) : bool
override DelegatingEqualityComparer.GetHashCode : a:'a -> int
Full name: Script.DelegatingEqualityComparer`1.GetHashCode
Object.GetHashCode() : int
IEqualityComparer.GetHashCode(obj: 'a) : int
Multiple items
type StringComparerInvariantCultureIgnoreCase =
inherit DelegatingEqualityComparer<string>
new : unit -> StringComparerInvariantCultureIgnoreCase
Full name: Script.StringComparerInvariantCultureIgnoreCase
--------------------
new : unit -> StringComparerInvariantCultureIgnoreCase
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
type StringComparer =
member Compare : x:obj * y:obj -> int + 1 overload
member Equals : x:obj * y:obj -> bool + 1 overload
member GetHashCode : obj:obj -> int + 1 overload
static member Create : culture:CultureInfo * ignoreCase:bool -> StringComparer
static member CurrentCulture : StringComparer
static member CurrentCultureIgnoreCase : StringComparer
static member InvariantCulture : StringComparer
static member InvariantCultureIgnoreCase : StringComparer
static member Ordinal : StringComparer
static member OrdinalIgnoreCase : StringComparer
Full name: System.StringComparer
property StringComparer.InvariantCultureIgnoreCase: StringComparer
Multiple items
type StringComparerInvariantCulture =
inherit DelegatingEqualityComparer<string>
new : unit -> StringComparerInvariantCulture
Full name: Script.StringComparerInvariantCulture
--------------------
new : unit -> StringComparerInvariantCulture
property StringComparer.InvariantCulture: StringComparer
val doSomething : data:Dictionary<string,'a,StringComparerInvariantCultureIgnoreCase> -> unit
Full name: Script.doSomething
val data : Dictionary<string,'a,StringComparerInvariantCultureIgnoreCase>
Multiple items
type Dictionary<'TKey,'TValue> =
new : unit -> Dictionary<'TKey, 'TValue> + 5 overloads
member Add : key:'TKey * value:'TValue -> unit
member Clear : unit -> unit
member Comparer : IEqualityComparer<'TKey>
member ContainsKey : key:'TKey -> bool
member ContainsValue : value:'TValue -> bool
member Count : int
member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
member Item : 'TKey -> 'TValue with get, set
...
nested type Enumerator
nested type KeyCollection
nested type ValueCollection
Full name: System.Collections.Generic.Dictionary<_,_>
--------------------
type Dictionary<'TKey,'TValue,'TComparer (requires equality and 'TComparer :> IEqualityComparer<'TKey>)> =
inherit Dictionary<'TKey,'TValue>
new : comparer:'TComparer -> Dictionary<'TKey,'TValue,'TComparer>
Full name: Script.Dictionary<_,_,_>
--------------------
Dictionary() : unit
Dictionary(capacity: int) : unit
Dictionary(comparer: IEqualityComparer<'TKey>) : unit
Dictionary(dictionary: IDictionary<'TKey,'TValue>) : unit
Dictionary(capacity: int, comparer: IEqualityComparer<'TKey>) : unit
Dictionary(dictionary: IDictionary<'TKey,'TValue>, comparer: IEqualityComparer<'TKey>) : unit
--------------------
new : comparer:'TComparer -> Dictionary<'TKey,'TValue,'TComparer>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val data : Dictionary<string,int,StringComparerInvariantCulture>
Full name: Script.data
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val data2 : Dictionary<string,int,StringComparerInvariantCultureIgnoreCase>
Full name: Script.data2
active recognizer KeyValue: KeyValuePair<'Key,'Value> -> 'Key * 'Value
Full name: Microsoft.FSharp.Core.Operators.( |KeyValue| )
val k : string
val v : int
Dictionary.Add(key: string, value: int) : unit
More information