How can I write a function that works on Vector{T1} as well as Vector{Union{T1, T2}}?
So for example I want the function to work on ["hello", "world", missing] as well as `[“hello”, “world”].
I can’t dispatch to the individual types, the vector is important.
Thanks a lot in advance!
f(v::Vector{T}) where T<:Union{String,Missing} = typeof(v)
or the shorthand
f(v::Vector{<:Union{String,Missing}}) = typeof(v)
3 Likes
Note that this will also include Vector{Missing} (as well as Vector{Union{}} FWIW). If you don’t want that, you could specify the type as:
f(v::Vector{T}) where String<:T<:Union{String,Missing} = typeof(v)
which will only allow Vector{String} and Vector{Union{String, Missing}}.
6 Likes
Thanks a lot for that hint, this is exactly what I was looking for!
Interesting
Could you elaborate a bit what String<:T<:Union{String,Missing} means in this context?
And another question for my education: Would one actually encounter a Vector{Union{}} in the wild? I have only been able to deliberately construct one by doing typeof(Union{}[]) = Vector{Union{}} because on the other hand typeof([Union{}]) = Vector{Core.TypeofBottom}.
Finally, I would probably not exclude Vector{Missing} because if I was expecting a Vector{T,Missing} there is the possibility that all values are missing in which case type inference might return the former type. Unless you want a specific method for that case but then defining f(::Vector{Missing}) would still work because it is more specific, no?
It just means that T must be a supertype of String, as well as a subtype of Union{String,Missing}. This excludes Missing since it’s not a supertype of String.
Yes, an empty vector with element type Union{} is sometimes useful. BangBang.jl for example uses it as a neutral element for reductions producing vectors, because promote_type(Union{}, T) is always just T (see Home · BangBang.jl). You can never have any defined elements in a Vector{Union{}} though, since the defining property of the bottom type is that it can not have any instances.
2 Likes