TupleDicts are type-stable dictionaries which support multiple sets of key-value pair types
Say you would like to make the following Dict, but you want key retrieval to be type stable
using Test
d = Dict{Union{Int,Float64,String},Union{Int,Float64}}(1 => 2, 2.0 => 3.0, "three" => 4)
@inferred d[1] # Inference fails because it infers Union{Int, Float64}A TupleDict can be constructed by passing in a tuple of Dicts, and it preserves the association of each keytype to its correspdonding valtype.
These Dicts can then be treated as one single Dict, while maintaining type stable retrieval
using ConcreteTupleDicts
d1 = Dict(1 => 2)
d2 = Dict(2.0 => 3.0)
d3 = Dict("three" => 4)
ds = (d1, d2, d3)
td = TupleDict(ds)
@inferred td[1] # Properly infers Int
@inferred td[2.0] # Properly infers Float64
@inferred td["three"] # Properly infers IntThese Dicts must not have overlapping key types in order to permit an unambiguous mapping from a given keytype to a valtype.
d1 = Dict(1 => 2)
d2 = Dict(3 => 4.0)
TupleDict((d1, d2)) # Throws an error, Int maps to both Int and Float64But TupleDicts are smart enough to merge keytypes which map to the same valtype
d1 = Dict(1 => 2)
d2 = Dict{Union{Int, String}, Int}(3 => 4, "five" => 6)
td = TupleDict((d1, d2)) # no issues, everything unamibuously maps to `Int`
@inferred td["five"] # Properly infers IntAnd the expected Dict behavior is still there
d1 = Dict(1 => 2)
d2 = Dict(2.0 => 3.0)
d3 = Dict("three" => 4)
ds = (d1, d2, d3)
td = TupleDict(ds)
keytype(td) # Union{Float64, Int64, String}
valtype(td) # Union{Float64, Int64)