<p dir="auto">Based on the discussion <a href="https://discourse.julialang.org/t/getting-union-tuple-covariance-for-maps-between-parallel-type-hierarchies/70060/6" rel="nofollow">https://discourse.julialang.org/t/getting-union-tuple-covariance-for-maps-between-parallel-type-hierarchies/70060/6</a></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="abstract type Continuous end
abstract type Count end

Scitype(::Type{&lt;:Integer}) = Count
Scitype(::Type{&lt;:AbstractFloat}) = Continuous

Scitype(::Type{Union{A,B}}) where {A&lt;:Integer,B} = Union{Count,Scitype(B)}
# Scitype(::Type{Union{A,B}}) where {A,B&lt;:AbstractFloat} = Union{Scitype(A),Continuous}

println(Scitype(Union{Int,Float64}))"><pre class="notranslate"><code class="notranslate">abstract type Continuous end
abstract type Count end

Scitype(::Type{&lt;:Integer}) = Count
Scitype(::Type{&lt;:AbstractFloat}) = Continuous

Scitype(::Type{Union{A,B}}) where {A&lt;:Integer,B} = Union{Count,Scitype(B)}
# Scitype(::Type{Union{A,B}}) where {A,B&lt;:AbstractFloat} = Union{Scitype(A),Continuous}

println(Scitype(Union{Int,Float64}))
</code></pre></div>
<p dir="auto">fails with</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ERROR: LoadError: StackOverflowError:"><pre class="notranslate"><code class="notranslate">ERROR: LoadError: StackOverflowError:
</code></pre></div>
<p dir="auto">whereas</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="abstract type Continuous end
abstract type Count end

Scitype(::Type{&lt;:Integer}) = Count
Scitype(::Type{&lt;:AbstractFloat}) = Continuous

# Scitype(::Type{Union{A,B}}) where {A&lt;:Integer,B} = Union{Count,Scitype(B)}
Scitype(::Type{Union{A,B}}) where {A,B&lt;:AbstractFloat} = Union{Scitype(A),Continuous}

println(Scitype(Union{Int,Float64}))"><pre class="notranslate"><code class="notranslate">abstract type Continuous end
abstract type Count end

Scitype(::Type{&lt;:Integer}) = Count
Scitype(::Type{&lt;:AbstractFloat}) = Continuous

# Scitype(::Type{Union{A,B}}) where {A&lt;:Integer,B} = Union{Count,Scitype(B)}
Scitype(::Type{Union{A,B}}) where {A,B&lt;:AbstractFloat} = Union{Scitype(A),Continuous}

println(Scitype(Union{Int,Float64}))
</code></pre></div>
<p dir="auto">succeeds with</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Union{Continuous, Count}"><pre class="notranslate"><code class="notranslate">Union{Continuous, Count}
</code></pre></div>
<p dir="auto">This looks illogical. Tested on 1.6.3</p>
<p dir="auto">in a fresh Mac v1.6.2 session:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; function f1(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}},
                    y::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
                    α::T = T(3.0) ) where {T&lt;:Real}
           println(typeof(x), &quot; &quot;, typeof(y))
       end;

julia&gt; f1([1.0, missing], [2.0, missing])
ERROR: MethodError: no method matching Union{Missing, Float64}(::Float64)
Stacktrace:
 [1] f1(x::Vector{Union{Missing, Float64}}, y::Vector{Union{Missing, Float64}})
   @ Main ./REPL[1]:4
 [2] top-level scope
   @ REPL[2]:1

julia&gt; function f2(x::Union{AbstractArray{T}, AbstractArray{&lt;:Union{T, Missing}}},
                   y::Union{AbstractArray{T}, AbstractArray{&lt;:Union{T, Missing}}};
                   α::T = T(3.0) ) where {T&lt;:Real}
           println(typeof(x), &quot; &quot;, typeof(y))
       end;

julia&gt; f2([1.0, missing], [2.0, missing])
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}"><pre class="notranslate"><code class="notranslate">julia&gt; function f1(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}},
                    y::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
                    α::T = T(3.0) ) where {T&lt;:Real}
           println(typeof(x), " ", typeof(y))
       end;

julia&gt; f1([1.0, missing], [2.0, missing])
ERROR: MethodError: no method matching Union{Missing, Float64}(::Float64)
Stacktrace:
 [1] f1(x::Vector{Union{Missing, Float64}}, y::Vector{Union{Missing, Float64}})
   @ Main ./REPL[1]:4
 [2] top-level scope
   @ REPL[2]:1

julia&gt; function f2(x::Union{AbstractArray{T}, AbstractArray{&lt;:Union{T, Missing}}},
                   y::Union{AbstractArray{T}, AbstractArray{&lt;:Union{T, Missing}}};
                   α::T = T(3.0) ) where {T&lt;:Real}
           println(typeof(x), " ", typeof(y))
       end;

julia&gt; f2([1.0, missing], [2.0, missing])
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}
</code></pre></div>
<p dir="auto">error seems coming from mistaking <code class="notranslate">Union{Missing, Float64}</code> as <code class="notranslate">T</code>, which should be <code class="notranslate">Float64</code>, in the default keyword argument assignment.</p>
<p dir="auto">noted that if I supply the keyboard argument such that <strong>the default value assignment is not called</strong>, no error:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; f1([1.0, missing], [2.0, missing]; α = 2.2)
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}"><pre class="notranslate"><code class="notranslate">julia&gt; f1([1.0, missing], [2.0, missing]; α = 2.2)
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}
</code></pre></div>
<p dir="auto">it seems to be <strong>a bug in extracting</strong> the <code class="notranslate">T</code> (when <code class="notranslate">Union</code> is involved?).</p>
<p dir="auto">the original discussion is from <a href="https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953" rel="nofollow">here</a>. Thanks.</p>