Function with vector of Union-Type

This does work:

function _foo1(_range::AbstractVector=[1,2])
    println(_range)
end

_foo1([1, missing])

This fails:

function _foo2(_range::Vector{Union{<:Number, Missing}}=[1, 2])
    println(_range)
end
_foo2([1, missing])

I do not understand why the second variant fails with the message:

ERROR: MethodError: no method matching _foo2(::Vector{Union{Missing, Int64}})
Closest candidates are:
  _foo2() at c:\data\git_repos\hycenta_stefan_pofahl\projects\Calibration\dbg_scripts\analyse_phase_sweep_dbg_output.jl:120
  _foo2(::Vector{Union{Missing, Number}}) at c:\data\git_repos\hycenta_stefan_pofahl\projects\Calibration\dbg_scripts\analyse_phase_sweep_dbg_output.jl:120

I think it’s due to the invariance of Julia type parameters: Vector{Union{<:Number,Missing}} is not a Vector{Missing,Int64}. You probably want the type signature of _foo2() to be:

function _foo2(_range::Vector{<:Union{<:Number,Missing}})
1 Like

To extend @brainandforce’s answer, your approach does not work because

julia> Vector{Union{Missing, Int}} <: Vector{Union{Missing, <:Number}}
false

(note that Vector{Union{Missing, <:Number} is a shorthand for Vector{Union{Missing, T} where T<:Number})
However,

julia> Vector{Union{Missing, Int}} <: Vector{Union{Missing, T}} where T <: Number
true

Therefore, you can define your function as

function _foo2(_range::Vector{Union{T, Missing}}=[1, 2]) where T <: Number

See also https://docs.julialang.org/en/v1/manual/types/#UnionAll-Types

This does not work for me. I have to add <: befor Union{}:

function _foo_B(_range::Vector{Union{T, Missing}}=[1, 2]) where T <: Number
    println(_range)
end
_foo_B()

Error:

ERROR: MethodError: no method matching _MyLibFunctionWithUnionType_B(::Vector{Int64})

Sorry, my bad. Indeed, my approach will only work if at least one element of _range is missing. Otherwise it won’t work because e.g.

julia> Vector{Int} <: Vector{Union{Missing, T}} where T <: Number
false

even though

julia> Int <: Union{Missing, T} where T <: Number
true