Dict merge without promoting

Is there any existing way to merge without promotion? Maybe with constructing a dict that has union type? Right now I’m trying to merge dicts that may have values of Int or Float type, in an arbitrary order, and I need the values to retain their type. Is there a way to do this aside from simply writing my own method?

(also, is there a particular reason why merge works with promotion? For me at least it led to an error that was hard to track down, and seems somewhat surprising)

Yes, you can use a union type or just Any:

D = Dict{Int,Any}()
D[1] = 2
D[2] = 3.0

If you need the key not to promote, you’ll need to use your own wrapper as far as I know. The key compares by hash, which per the docs says that


Compute an integer hash code such that isequal(x,y) implies hash(x)==hash(y). The optional second argument h is a
  hash code to be mixed with the result.

You could create a Dict of whatever type you want and use merge!,

julia> d1 = Dict(1 => 2); d2 = Dict(2. => 3.); d3 = Dict{Union{Int, Float64}, Union{Int, Float64}}();

julia> merge!(d3, d1, d2)
Dict{Union{Float64, Int64},Union{Float64, Int64}} with 2 entries:
  2.0 => 3.0
  1   => 2

I misunderstood what was being asked, as I was thinking the question pertained to keys being promoted. So if it’s expected that d[1.0] != d[1], you’d need a wrapper type.