Problem with parametric method definition


How to adjust definition of f so it works for both As and Bs types in the following code:

struct A end
struct B{b} end

va = Vector{Union{A, Missing}}()
vb = Vector{Union{B, Missing}}()

f(v::Vector{Union{t, Missing}}, i::t) where t = nothing  

f(va, A())
f(vb, B{:b}())

Of course I would like to avoid i::Any in the method definition.


I am not sure if this is what you want to do, but if you do

vb = Vector{Union{B{:b}, Missing}}()

your code would work. In this case t would have the same type both in the array and in the scalar.

I need vb to contain all type of Bs.

Since B (without the parameter) is not a concrete type, I would recommend something like

f(v::Vector{Union{<: B, Missing}}, i::B) = :testB
f(v::Vector{Union{A, Missing}}, i::A) = :testA

I don’t think you can combine these into a single method signature, but someone may suggest a solution. In any case, I think that using two signatures is more readable.

It is possible that you want AbstractVector instead of Vector, unless you have a very compelling reason.

Finally, it is not clear from your example if you want to do this, but conditioning semantics on container types is not good practice IMO. Code should work the same for Vector{Any} and Vector{T}, if the elements are otherwise identical. Also, if vb contains various B{T}s, you may not get any performance gains from narrowing the element type since B is not a concrete type.

Thanks a lot for explanations.