Как использовать объединение массива и параметрического NTuple как тип аргумента функции в Юлии? - PullRequest
0 голосов
/ 02 июня 2018

Я пытаюсь написать функцию, которая принимает аргумент, который может быть кортежем или массивом.Это работает, например:

julia> temp(x::Union{Vector{Int64},NTuple{4,Int64}}) = sum(x)
temp (generic function with 1 method)

julia> temp((3,1,5,4))
13

julia> temp([3,1,5,4])
13

С другой стороны, когда я пытаюсь использовать кортеж неопределенной длины, он не работает для массива:

julia> temp(x::Union{Vector{Int64},NTuple{N,Int64}}) where N = sum(x)
temp (generic function with 1 method)

julia> temp([3,1,5,4])
ERROR: MethodError: no method matching temp(::Array{Int64,1})
Closest candidates are:
  temp(::Union{Array{Int64,1}, Tuple{Vararg{Int64,N}}}) where N at REPL[1]:1

julia> temp((3,1,5,4))
13

Разве это неспособ делать вещи?Я понимаю, что могу решить эту проблему, используя множественную диспетчеризацию:

julia> temp(x::Vector{Int64}) = sum(x)
temp (generic function with 1 method)

julia> temp(x::NTuple{N,Int64}) where N = sum(x)
temp (generic function with 2 methods)

julia> temp((3,1,5,4))
13

julia> temp([3,1,5,4])
13

, но я пытаюсь понять, как работает Union в Юлии, и задаюсь вопросом, есть ли способ добиться этого, используя его.

1 Ответ

0 голосов
/ 02 июня 2018

Поведение отличается между Юлией 0,6,3 и Юлией 0,7-альфа.То, что мы имеем в Julia 0.7-alpha, более согласованно, так как в этом случае не имеет значения местоположение пункта where.

Случай Julia 0.6.3

У вас есть два способа исправитьпроблема с перемещением предложения where внутри определения функции:

julia> temp1(x::Union{Vector{Int64},NTuple{N,Int64}} where N) = sum(x)
temp1 (generic function with 1 method)

julia> temp1([3,1,5,4])
13

julia> temp1((3,1,5,4))
13

julia> temp2(x::Union{Vector{Int64},NTuple{N,Int64} where N}) = sum(x)
temp2 (generic function with 1 method)

julia> temp2([3,1,5,4])
13

julia> temp2((3,1,5,4))
13

также вы можете избежать необходимости указывать where N, используя Vararg, например:

julia> temp3(x::Union{Vector{Int64}, Tuple{Vararg{Int64}}}) = sum(x)
temp3 (generic function with 1 method)

julia> temp3((3,1,5,4))
13

julia> temp3([3,1,5,4])
13

СлучайЮлия 0,7-альфа

Ваша функция будет просто работать:

julia> temp(x::Union{Vector{Int64},NTuple{N,Int64}}) where N = sum(x)
temp (generic function with 1 method)

julia> temp([3,1,5,4])
13

julia> temp((3,1,5,4))
13

также temp1, temp2 и temp3 будут работать.

...