When I tried to construct Union
of Vararg
like
julia> Union{Vararg{Any, 1}, Vararg{Any, 2}}
I got
ERROR: TypeError: in Union, expected Type, got Vararg{Any, 1}
but clearly
julia> Vararg{Any, 1} isa Type
true
julia> [Vararg{Any, 1}, Vararg{Any, 2}] isa Array{<:Type, 1}
true
Is this intended behavior and I’m missing something here? Thank you!
frankwswang:
Vararg{Any, 1} isa Type
Vararg shouldn’t be a Type
this is a bug in previous Julia versions and has been fixed in Julia 1.7, See also: Vararg subtyping is inconsistent between 1.0 and 1.6 · Issue #40405 · JuliaLang/julia · GitHub
not sure if this can be backported to 1.6 if 1.6 is gonna be LTS tho, @kristoffer.carlsson probably knows
4 Likes
Thank you, Roger! Then if I want to realize a similar goal here, do you know there’s a way to do that? Specifically, I want to control the allowed N
in Vararg{T, N} as the type of the argument type for a function in an efficient way. For example, only allow the number of arguments to be 1,2,3,4.
I know I can at least do it by:
foo(a1=nothing, a2=nothing, a3=nothing, a4=nothing) = []
Thank you!
note, Vararg
means less than N
arguments, thus it doesn’t make sense to have Union{Vararg{Any, 1}, Vararg{Any, 2}}
either
julia> foo(xs::Vararg{Int, 4}) = xs
foo (generic function with 1 method)
julia> foo(1,2,3,4)
(1, 2, 3, 4)
julia> foo(1,2,3,4, 5)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64, ::Int64, ::Int64)
Closest candidates are:
foo(::Int64, ::Int64, ::Int64, ::Int64) at REPL[1]:1
Stacktrace:
[1] top-level scope
@ REPL[3]:100:
I think Vararg{T, 4}
means “exactly N
type-T
arguments”?
julia> foo(xs::Vararg{Int, 4}) = xs
foo (generic function with 1 method)
julia> foo(1,2,3,4)
(1, 2, 3, 4)
julia> foo(1,2,3)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64)
1 Like
oh yeah, you are right, that’s exactly N
arguments.
then you can do the following
julia> for N in [1, 4]
@eval foo(xs::Vararg{Int, $N}) = xs
end
julia> foo(1)
(1,)
julia> foo(2)
(2,)
julia> foo(2, 3)
ERROR: MethodError: no method matching foo(::Int64, ::Int64)
Closest candidates are:
foo(::Int64, ::Int64, ::Int64, ::Int64) at REPL[8]:2
foo(::Int64) at REPL[8]:2
Stacktrace:
[1] top-level scope
@ REPL[11]:1
This seems like an alternative solution. Thank you!