# Understanding Types Union{}

**URL:** <https://discourse.julialang.org/t/understanding-types-union/103466>\
**Category:** New to Julia\
**Tags:** question, type, union\
**Created:** [September 2, 2023, 4:28pm UTC](https://discourse.julialang.org/t/understanding-types-union/103466 "2023-09-02T16:28:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Denis\_Ivanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/denis_ivanov/32/52607_2.png) [@Denis\_Ivanov](https://discourse.julialang.org/u/Denis_Ivanov)\
**Post date:** [September 2, 2023, 4:28pm UTC](https://discourse.julialang.org/t/understanding-types-union/103466/1 "2023-09-02T16:28:54Z")

</div>

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_:

```julia
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

```julia
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!

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 2, 2023, 4:43pm UTC](https://discourse.julialang.org/t/understanding-types-union/103466/2 "2023-09-02T16:43:16Z")

</div>

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}}})`.

---

<div class="post-metadata">

**Author:** ![Denis\_Ivanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/denis_ivanov/32/52607_2.png) [@Denis\_Ivanov](https://discourse.julialang.org/u/Denis_Ivanov)\
**Post date:** [September 2, 2023, 4:50pm UTC](https://discourse.julialang.org/t/understanding-types-union/103466/3 "2023-09-02T16:50:12Z")

</div>

> [@nsajko](#):
>
> Vector{\<:Union{Int8,Vector{Int8}}}

Thank you that’s work!

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [September 2, 2023, 9:24pm UTC](https://discourse.julialang.org/t/understanding-types-union/103466/4 "2023-09-02T21:24:54Z")

</div>

`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
julia> isconcretetype(Union{Vector{Int64}, Vector{Vector{Int64}}})
false

julia> isconcretetype(Vector{Int64})
true

```

The following holds though,

```julia
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
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.
