Here's how I'd tackle this problem: I'd use dispatch with promote_type to
perform the type reduction. This is often the best way to express things
like this:
scalar_or_eltype{T}(::AbstractArray{T}) = T
scalar_or_eltype{T}(::T) = T
promote_scalar_or_eltype(A, B) = promote_type(scalar_or_eltype(A),
scalar_or_eltype(B))
promote_scalar_or_eltype(A, B, args...) = promote_type(scalar_or_eltype(A),
promote_scalar_or_eltype(B, args...))
julia> @code_warntype promote_scalar_or_eltype(1, [1,2,3], 3., 4, 1//2,
[0x1,0x2])
Variables:
A::Int64
B::Array{Int64,1}
args::Tuple{Float64,Int64,Rational{Int64},Array{UInt8,1}}
##args#7194::Tuple{Int64,Rational{Int64},Array{UInt8,1}}
####args#7192#7195::Tuple{Rational{Int64},Array{UInt8,1}}
######args#7191#7193#7196::Tuple{Array{UInt8,1}}
Body:
begin # none, line 1:
return Float64
end::Type{Float64}
And then I'd define your special `vcat` signature as simply being
`my_vcat(args::Union{Number, AbstractVector}...)`.
On Tuesday, October 20, 2015 at 10:21:11 AM UTC-4, Andras Niedermayer wrote:
>
> I had actually tried the same (even called it "success2" like you :-). But
> this seems to shift the problem one step further back:
>
> dispatchtest{T}(x::Array{T,1},y::Vararg{Union{T,Array{T,1}}}) = "success2"
> dispatchtest([1,2],[3,6],[3,4],5)
>
>
> results in
>
> LoadError: MethodError: `dispatchtest` has no method matching
> dispatchtest(::Array{Int64,1}, ::Array{Int64,1}, ::Array{Int64,1}, ::Int64)
> Closest candidates are:
> dispatchtest{T}(::Array{T,1}, !Matched::Union{Array{T,1},T}...)
> dispatchtest{T}(!Matched::Union{AbstractArray{T,1},T}...)
> while loading In[5], in expression starting on line 1
>
>
> On Tuesday, October 20, 2015 at 4:10:41 PM UTC+2, Dan wrote:
>>
>> This might have something to do with matching parameter T correctly. T
>> could actually be an Array type and then Array{T,1} would be an Array of
>> Arrays. This is creates ambiguity.
>>
>> In any case, a solution might be to define:
>> dispatchtest{T}(x0::Array{T,1},x::Vararg{Union{T,Array{T,1}}}) =
>> "success2"
>>
>> This way, the problematic case goes to "success2" and can be handled
>> appropriately.
>>
>> On Tuesday, October 20, 2015 at 3:05:31 PM UTC+3, Kristoffer Carlsson
>> wrote:
>>>
>>> Not sure why it doesn't work when the array comes first:
>>>
>>>
>>> julia> dispatchtest(2,[1,2])
>>> "success"
>>>
>>> julia> dispatchtest(2,[1,2],2)
>>> "success"
>>>
>>> julia> dispatchtest(2,[1,2],2,[1,2])
>>> "success"
>>>
>>> julia> dispatchtest([1,2],2,[1,2],2,[1,2])
>>> ERROR: MethodError: `dispatchtest` has no method matching dispatchtest
>>> (::Array{Int64,1}, ::Int64, ::Array{Int64,1}, ::Int64, ::Array{Int64,1})
>>> Closest candidates are:
>>> dispatchtest{T}(::Union{Array{T,1},T}...)
>>> dispatchtest{T}(::Union{Array{T,1},T}...)
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Tuesday, October 20, 2015 at 1:33:37 PM UTC+2, Andras Niedermayer
>>> wrote:
>>>>
>>>> This doesn't work:
>>>> dispatchtest{T}(x::Vararg{Union{T,Array{T,1}}}) = "success"
>>>> dispatchtest([1,2],3)
>>>>
>>>>
>>>> results in
>>>>
>>>> LoadError: MethodError: `dispatchtest` has no method matching
>>>> dispatchtest(::Array{Int64,1}, ::Int64)
>>>> Closest candidates are:
>>>> dispatchtest{T}(!Matched::Union{Array{T,1},T}...)
>>>> while loading In[8], in expression starting on line 1
>>>>
>>>>
>>>>
>>>> On Tuesday, October 20, 2015 at 1:19:24 PM UTC+2, Kristoffer Carlsson
>>>> wrote:
>>>>>
>>>>> Try: Base.vcat{T}(x::Vararg{Union{T,Array{T,1}}}) = mixed_vcat(x...)
>>>>>
>>>>> On Tuesday, October 20, 2015 at 11:44:15 AM UTC+2, Andras Niedermayer
>>>>> wrote:
>>>>>>
>>>>>> I've written an implementation of vcat for the special case of mixed
>>>>>> scalar-vector parameters (e.g. vcat(1,[2,3],4)) using generated
>>>>>> functions.
>>>>>> I get a speed increase of a factor 70 and memory usage reduction by a
>>>>>> factor 10. It also makes this special case of vcat type stable (e.g. the
>>>>>> inferred type is Array{Int64,1} rather than Any for vcat(1,[2,3],4)). See
>>>>>> https://gist.github.com/afniedermayer/947faadd362778d088d7
>>>>>>
>>>>>> I'd like to make a pull request (or at least provide a package that
>>>>>> overloads vcat to start with), but I haven't figured out how to dispatch
>>>>>> on
>>>>>> mixed scalar-vector parameters.
>>>>>> Base.vcat{T}(x::Union{T,Array{T,1}}...) = mixed_vcat(x...)
>>>>>>
>>>>>>
>>>>>> doesn't work, see
>>>>>> https://groups.google.com/forum/#!topic/julia-users/NCfxu7_9VR0
>>>>>>
>>>>>> Is there a way to dispatch on mixed scalar-vector parameters (besides
>>>>>> dispatching in the generated function)?
>>>>>>
>>>>>