# Concrete types for Dicts in container

Hi everyone!

I am trying to construct a container that holds vectors of different probabilities (but they are all either multi- or univariate). This container is used to store prior distributions of parameter I use in another struct, so one of the fields is a Dict that maps symbols to Vectors of distributions. The following could be used for a concrete type definition:

``````using Distributions
using BenchmarkTools

#3 - Issue for concrete types
typeof( [Normal(), Normal() ] ) #Vector{Normal{Float64}}
typeof( [Gamma(1,2), Normal() ] ) #Vector{Distribution{Univariate, Continuous}}
typeof( [Normal(), Normal() ] ) <: Vector{<:Distribution{Univariate} } #true
typeof( [Gamma(1,2), Normal() ] ) <: Vector{<:Distribution{Univariate} } #true
typeof( [Poisson(1), Normal() ] ) <: Vector{<:Distribution{Univariate} } #true

#all combinations above are subtype of Vector{<:Distribution{Univariate} }
Dict(:μ => [Normal(1,2), Normal(3,4)],
:δ => [Gamma(1,1), Exponential(1)] ) #Dict Symbol -> Array{T,1} where T
#but somehow here no concrete type is assigned
``````

So as a first guess I would assign the following container:

``````struct Prior01{A<:VariateForm}
α       ::  Dict{Symbol, Vector{<:Distribution{A}} }
end
# Concretely typed not working
p01 = Prior01( Dict(:μ => [Normal(1,2), Gamma(3,4)],
:δ => [Gamma(1,1), Gamma(1,1)] )  )
``````

For some reasons I do not understand, this is not working - so a non-concretely typed version so far is the best I could do:

``````struct Prior02
α       ::  Dict{Symbol, <:Vector{C} where {C} }
end

#Working but no concrete type
p02 = Prior02( Dict(:μ => [Gamma(1,2), Gamma(3,4)],
:δ => [Gamma(1,1), Gamma(1,1)] )  )
``````

Question: Does anyone know why I cannot get the concretely typed container working even though the Vectors of Distributions shown above have a common supertype?

Best regards,

Does `eltype()` return the same for `[Gamma(1,2), Gamma(3,4)]` and `[Gamma(1,1), Gamma(1,1)]`? If not, then their closest common supertype is indeed `Vector{<:Any}`.
If you want to have `Vector{Distribution}` as the value type for the dictionary, then use it explicitly when calling the constructor:

``````p02 = Prior02( Dict{Symbol, Vector{Distribution}}(:μ => [Normal(1,2), Gamma(3,4)],
:δ => [Gamma(1,1), Gamma(1,1)] )  )
``````

Note, however, that `Vector{Distribution}` isn’t a concrete type, so you still get boxing there. But that still provides a hint to the type inference system.

2 Likes

I don’t think this matters in practice. For the compiler, it is commonly just best to bail to `Any` for non-concrete types.

1 Like

Thank you for your answer! `eltype()`does return the same for
`[Gamma(1,2), Gamma(3,4)]` and `[Gamma(1,1), Gamma(1,1)]`, but not for
`[Normal(1,2), Gamma(3,4)]` and `[Gamma(1,1), Gamma(1,1)]`,
which I think you might have meant?

In that case, I will have to resort to `Any`then, as you two suggested.