I tried to write a special case of vcat which improves type inference to get around this problem:
f() = vcat(1,[2,3]) @code_warntype f() gives Variables: ... end::ANY This works: function my_vcat{T}(x::T, y::AbstractArray{T}) result = Array(T, length(y)+1 ) result[1] = x result[2:end] = y return result end f2() = my_vcat(1,[2,3]) @code_warntype f2() and gives Variables: Body: begin # In[4], line 1: return (Main.my_vcat)(1,(top(vect))(2,3)::Array{Int64,1})::Array{Int64,1} end::Array{Int64,1} I wanted to generalize this, but get unexpected behavior: my_vcat{T}(x::Union{T,Array{T,1}}...) = "foo" # code to be added my_vcat(1,[2,3],4) # returns "foo" as expected my_vcat([1,2],3) # throws this exceptions: LoadError: MethodError: `my_vcat` has no method matching my_vcat(::Array{Int64,1}, ::Int64) Closest candidates are: my_vcat{T}(!Matched::Union{Array{T,1},T}...) my_vcat{T}(!Matched::Union{Array{T,1},T}...) my_vcat{T}(::T, !Matched::AbstractArray{T,N}) while loading In[11], in expression starting on line 1 Defining my_vcat{T}(x::Union{Array{T,1},T}...) = "foo" (the ordering of Array{T,1} and T has been changed) shows that a third method for my_vcat has been defined. Actually, every time I rerun the same line, an additional methods is defined. methods(my_vcat) shows 6 methods for generic function *my_vcat*: - my_vcat*{T}*(x::*T*, y::*AbstractArray{T,N}*) at In[8]:2 - my_vcat*{T}*(x::*Union{Array{T,1},T}...*) at In[1]:1 - my_vcat*{T}*(x::*Union{Array{T,1},T}...*) at In[2]:1 - my_vcat*{T}*(x::*Union{Array{T,1},T}...*) at In[3]:1 - my_vcat*{T}*(x::*Union{Array{T,1},T}...*) at In[4]:1 - my_vcat*{T}*(x::*Union{Array{T,1},T}...*) at In[5]:1 What's going on? And is there a way to achieve this with varargs and Unions (instead hard-coding every possible combination of T and Array{T})?