# Construct object of type whose type is UnionAll

**URL:** <https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 14, 2018, 7:33am UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332 "2018-04-14T07:33:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [April 14, 2018, 7:33am UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332/1 "2018-04-14T07:33:49Z")

</div>

The following does what I want

```julia
julia> (Dict{T,V} where {T,V})()
Dict{Any,Any} with 0 entries

```

It seems reasonable that this

```julia
julia> (Dict{T,Int} where T)()
ERROR: MethodError: no method matching Dict{T,Int64} where T()

```

should return `Dict{Any,Int} with 0 entries`. Even if there is a good reason why this is not so, what is the best way for me to construct an instance of `Dict{Any,Int}` from `Dict{T,Int} where T` ?

---

<div class="post-metadata">

**Author:** ![jamii](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jamii/32/1373_2.png) [@jamii](https://discourse.julialang.org/u/jamii)\
**Post date:** [April 14, 2018, 8:52am UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332/2 "2018-04-14T08:52:35Z")

</div>

`(Dict{T,V} where {T,V})()` is not normal type behavior, it’s a method defined specifically at [https://github.com/JuliaLang/julia/blob/master/base/dict.jl#L126](https://github.com/JuliaLang/julia/blob/master/base/dict.jl#L126)

But this works for any `where` type:

```julia
julia> t = Dict{T,Int} where T
Dict{T,Int64} where T

julia> t{Any}
Dict{Any,Int64}

julia> t{Any}()
Dict{Any,Int64} with 0 entries

```

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [April 14, 2018, 9:55am UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332/3 "2018-04-14T09:55:00Z")

</div>

It looks like `Dict() = Dict{Any,Any}()` is a convenience function rather than a degenerate case of generic behavior.

I’d like to do this generically, for any `UnionAll` type. Or, something less ambitious, find a solution for my use case: Given a collection of concrete dictionary types, I want to construct a dictionary of the narrowest type that will accept all keys and values of instances of the dictionaries in the collection.

```julia
 julia> a = [Dict{Symbol,Int}, Dict{Symbol,Symbol}, Dict{Symbol,String}];

julia> T = reduce(typejoin,a)
Dict{Symbol,V} where V

julia> T()
ERROR: MethodError: no method matching Dict{Symbol,V} where V()

```

Defining `T()` generically might not be more widely useful. In that case a function, say `construct(T)` would do.

EDIT: I don’t mean strictly “narrowest”. I’d like to follow `typejoin`:

```julia
julia> typejoin(Dict{Symbol,Int}, Dict{Symbol,Float64})
Dict{Symbol,V} where V

```

---

<div class="post-metadata">

**Author:** ![jamii](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jamii/32/1373_2.png) [@jamii](https://discourse.julialang.org/u/jamii)\
**Post date:** [April 14, 2018, 12:44pm UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332/4 "2018-04-14T12:44:48Z")

</div>

It sounds like you want to typejoin the key and value types, not the dict type itself.

```julia
julia> keytype(::Type{Dict{K,V}}) where {K,V} = K
keytype (generic function with 1 method)

julia> valtype(::Type{Dict{K,V}}) where {K,V} = V
valtype (generic function with 1 method)

julia> a = [Dict{Symbol,Int}, Dict{Symbol,Symbol}, Dict{Symbol,String}]
3-element Array{DataType,1}:
 Dict{Symbol,Int64} 
 Dict{Symbol,Symbol}
 Dict{Symbol,String}

julia> t = Dict{reduce(typejoin, map(keytype, a)), reduce(typejoin, map(valtype, a))} 
Dict{Symbol,Any}

julia> t()
Dict{Symbol,Any} with 0 entries

```

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [April 14, 2018, 1:15pm UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332/5 "2018-04-14T13:15:13Z")

</div>

This gets me part of the way there. But, this gives

```julia
julia> a = [Dict{Symbol,Int}, Dict{Symbol,Float64}];

julia> t = Dict{mapreduce(keytype,typejoin,a), mapreduce(valtype,typejoin,a)}
Dict{Symbol,Real}

```

whereas

```julia
julia> typejoin(Dict{Symbol,Int}, Dict{Symbol,Float64})
Dict{Symbol,V} where V

```

I’ll think about how much generality I really need and post again.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [April 14, 2018, 5:37pm UTC](https://discourse.julialang.org/t/construct-object-of-type-whose-type-is-unionall/10332/6 "2018-04-14T17:37:31Z")

</div>

I think your solution plus `isconcretetype` (`isleaftype`) is enough. Thanks.

EDIT: I mean any type that is not concrete can be replaced with `Any`.
