Understanding Types Union{}

I read the manual about types carefully, but I can’t figure out how to do this.
Let’s two types of data are possible: Vector{Int8} and Vector{Vector{Int8}}
eg [1, 0, 1] and [[1, 1], [0]]

Following the recommendations, I wrote two implementations:
some_calc(vec::Vector{Int8}) and
some_calc(vec::Vector{Vector{Int8}})

They both work efficiently and recognise types.
But there are actions that have to be done anyway,
so there is a main function that should accept both types:

main_calc(vec::???)
…
some_calc(vec)
…
end

I tried to write Vector in place of ???, or just vec without type description -
nothing works. After studying the manual, I thought the right idea was
Union{Vector{Int8}, Vector{Vector{Int8}}}

But surprisingly

typeof([[1,2], [1,3]]) == Union{Vector{Int64}, Vector{Vector{Int64}}} → false
typeof([1,2,3]) == Union{Vector{Int64}, Vector{Vector{Int64}}} → false

I’m tracking the conversion Int64 → Int8 (it’s needed for performance, so there is no problem with it)
But the last results confused me!

PS. Why do I care so much about types? (Maybe it helps new users)
I do complex computations like fractal research.
And found that Julia is great for this, and with strict typing and right memory allocation much faster than Python etc. So Julia rocks!

If it’s just a single method you could just declare it like main_calc(vec), so without any type annotations. For more safety/strictness, you could use main_calc(vec::Vector). For even more strictness, you could use union types: main_calc(vec::Vector{<:Union{Int8,Vector{Int8}}}).

Thank you that’s work!

typeof([1,2,3]) == Union{Vector{Int64}, Vector{Vector{Int64}}} is false, because Vector{Int64} is not the same type as Union{Vector{Int64}, ...}. You can check for example

julia> isconcretetype(Union{Vector{Int64}, Vector{Vector{Int64}}})
false

julia> isconcretetype(Vector{Int64})
true

The following holds though,

julia> Vector{Int64} <: Union{Vector{Int64}, Vector{Vector{Int64}}}
true

as any type T is a subtype of a Union containing T or some supertype thereof.

Now, the type Vector{<:Union{Int64,Vector{Int64}}} is different as it specifies a vector where each element could be an Int64 or a Vector{Int64}:

julia> Vector{<:Union{Int64,Vector{Int64}}} == (Vector{T} where {T <: Union{Int64, Vector{Int64}}})
true
julia> [1, 2, 3] isa Vector{<:Union{Int64,Vector{Int64}}}
true
julia> [1, 2, 3] isa Union{Vector{Int64},Vector{Vector{Int64}}}
true
# Note: [1, [2], 3] constructs a Vector{Any} thus explicit types are needed here
julia> Union{Int64, Vector{Int64}}[1, [2], 3] isa Vector{<:Union{Int64, Vector{Int64}}}
true
julia> Union{Int64, Vector{Int64}}[1, [2], 3] isa Union{Vector{Int64}, Vector{Vector{Int64}}}
false

I.e., Union{Vector{Int64}, Vector{Vector{Int64}}} requires either a Vector{Int64} or Vector{Vector{Int64}}, but does not allow for mixed element types.