Во-первых, преобразование происходит из-за того, что объявление вашей функции объявляет тип возвращаемого значения. Если вы удалите (или закомментируете) аннотацию этого типа
function Γ(state::Dict{Symbol, <:Tuple{Vararg{Symbol}}}) #::Vector{NamedTuple{<:Tuple{Vararg{Symbol}}, <:Tuple{Vararg{Symbol}}}}
kwargs = Dict() # <- there was a typo here in your minimal example
keys = [key for (key, value) ∈ state]
instances_vec = [value for (key, value) ∈ state]
data = Vector{Vector{Symbol}}()
function recursive(data, current, depth = 1)
if depth <= length(instances_vec)
for instance ∈ instances_vec[depth]
recursive(data, push!(copy(current), instance), depth + 1)
end
else
push!(data, current)
end
end
recursive(data, [])
return [(;zip(keys,configuration)...) for configuration ∈ data]
end
, тогда все в порядке:
julia> identifiers = Dict(:Id=>(:One, :Two, :Three, :Four, :Five), :Nationality=>(:Brit, :German), :Color=>(:Red, :Blue, :Green))
Dict{Symbol,Tuple{Symbol,Symbol,Vararg{Symbol,N} where N}} with 3 entries:
:Id => (:One, :Two, :Three, :Four, :Five)
:Nationality => (:Brit, :German)
:Color => (:Red, :Blue, :Green)
julia> Γ(identifiers)
30-element Array{NamedTuple{(:Id, :Nationality, :Color),Tuple{Symbol,Symbol,Symbol}},1}:
(Id = :One, Nationality = :Brit, Color = :Red)
(Id = :One, Nationality = :Brit, Color = :Blue)
(Id = :One, Nationality = :Brit, Color = :Green)
[...]
Обратите внимание, что ввод аргументов функции / метода, где это необходимо, считается хорошей практикой , Тем не менее, код, который обеспечивает утверждения типа для возвращаемых значений, часто менее идиоматичен c в Джулии: компилятор действительно хорош в выяснении, что такое возвращаемый тип!
Теперь причина неудачного преобразования заключается в том, что тип элемента, указанный в сигнатуре, не соответствует фактическому типу элемента возвращаемого вектора:
julia> elem = (Id = :One, Nationality = :Brit, Color = :Red)
(Id = :One, Nationality = :Brit, Color = :Red)
julia> typeof(elem)
NamedTuple{(:Id, :Nationality, :Color),Tuple{Symbol,Symbol,Symbol}}
julia> elem isa NamedTuple{<:Tuple{Vararg{Symbol}}, <:Tuple{Vararg{Symbol}}}
false
Для совпадения NamedTuple{A,B}
NamedTuple{<:Tuple{Vararg{Symbol}},
<:Tuple{Vararg{Symbol}}}
, должны соблюдаться оба условия:
A <: Tuple{Vararg{Symbol}}
B <: Tuple{Vararg{Symbol}}
Здесь мы имеем:
A = (:Id, :Nationality, :Color)
B = Tuple{Symbol,Symbol,Symbol}
, так что, как вы сказали, выполняется условие для B
:
julia> B <: Tuple{Vararg{Symbol}}
true
, но не условие для A
:
julia> A <: Tuple{Vararg{Symbol}}
ERROR: TypeError: in <:, expected Type, got Tuple{Symbol,Symbol,Symbol}
Stacktrace:
[1] top-level scope at REPL[10]:1
# A is a value of type Tuple{...}, not the type itself
julia> typeof(A) <: Tuple{Vararg{Symbol}}
true