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