Function with Array of Abstract types as arguments

So, because

julia> Uniform{Float64} <: Distribution
true

julia> Array{Uniform{Float64},1} <: Array{Distribution}
false

I cannot make a function like

foo(a::Array{Distribution}) = nothing

and call it with

foo([Uniform(0,1)])

How do i correctly define foo to make this work ?

Oh nevermind, the answer is

function foo(a::Array{D,1}) where D <: Distribution
nothing
end

I was confused because

function foo(a::Distribution) 
nothing
end

foo(Uniform())

works without the need to define as foo(a <: Distribution)

1 Like

You can also write Array{<:Distribution,1} or Vector{<:Distribution}. To be more generic, maybe AbstractVector{<:Distribution}.

2 Likes

Oh thanks, I guess where is useful to make sure multiple arguments receive the same type.

Right, it is useful when types of arguments should be somehow related to each other: foo(x::T, v::AbtractArray{T}) where {T<:Real} or foo(x::T, y::S) where {T, S<:T}. Also useful when you want to instantiate an object of a specific argument-dependent type in the function body:

function foo(v::Vector{K}, w::Vector{V}) where {K,V}
    return Dict{K,V}(v .=> w)
end

The difference from just Dict(v .=> w) would be that if v and w are arrays of abstract types but happen to contain elements of a concrete type (say, both are arrays of Any but accidentally only contain strings when foo is called), Dict{K,V} may be what you actually want and a Dict of autodetected key and value types may be not.

1 Like