I’m trying to construct a Tuple containing a member NamedTuple from a Tuple. I believe this should work but it doesn’t.
julia> T = Tuple{Int64, Int64, NamedTuple{(:d, :e), Tuple{Int64, Int64}}};
julia> vals = (1,2,(3,4));
julia> T(vals)
ERROR: MethodError: Cannot `convert` an object of type Tuple{Int64, Int64} to an object of type NamedTuple{(:d, :e), Tuple{Int64, Int64}}
Closest candidates are:
convert(::Type{NamedTuple{names, T}}, ::NamedTuple{names, T}) where {names, T<:Tuple}
@ Base namedtuple.jl:148
convert(::Type{NamedTuple{names, T}}, ::NamedTuple{names}) where {names, T<:Tuple}
@ Base namedtuple.jl:151
convert(::Type{T}, ::T) where T
@ Base Base.jl:64
...
Stacktrace:
[1] cvt1
@ ./essentials.jl:418 [inlined]
[2] ntuple
@ ./ntuple.jl:50 [inlined]
[3] convert(#unused#::Type{Tuple{Int64, Int64, NamedTuple{(:d, :e), Tuple{Int64, Int64}}}}, x::Tuple{Int64, Int64, Tuple{Int64, Int64}})
@ Base ./essentials.jl:419
[4] Tuple{Int64, Int64, NamedTuple{(:d, :e), Tuple{Int64, Int64}}}(x::Tuple{Int64, Int64, Tuple{Int64, Int64}})
@ Base ./tuple.jl:364
[5] top-level scope
@ REPL[5]:1
There seem to be two solutions that I can see:
- Modify the Tuple constructor to construct each element explicitly:
(::Type{T})(x::Tuple) where {T<:Tuple} = tuple((type(arg) for (type, arg) in zip(T.parameters, x))...)
- Implement
Base.convert
for NamedTuples:
Base.convert(::Type{NT}, val::Tuple) where {NT<:NamedTuple} = NT(val)
Am I missing something obvious? Will either of these proposed solutions cause problems elsewhere?
Thanks for the feedback!