Is there an inherent reason that type management of NamedTuple
’s works differently from normal Tuple
’s (in 1.7 at least)?
In particular, is the behavior of the following second command (case 1.2) intended for something? If so, can you give an explaining example? I have not really been able to find a simpler logic behind the given functionality.
I have included more examples below (which are less important but still haunt me), but I think it all boils down to the weird(?) syntax of the following fourth command (case 1.4):
typeof(convert(Tuple{AbstractArray}, (1:2,)))
# Tuple{UnitRange{Int64}} (case 1.1)
typeof(convert(NamedTuple{(:a,),Tuple{AbstractArray}}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{AbstractArray}} (case 1.2)
typeof(convert(NamedTuple{(:a,),Tuple{T} where T<:AbstractArray}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{AbstractArray}} (case 1.3)
typeof(convert(NamedTuple{(:a,),<:Tuple{AbstractArray}}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{UnitRange{Int64}}} (case 1.4)
typeof(convert(NamedTuple{(:a,),Tuple{UnitRange}}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{UnitRange}} (case 1.5)
Since for Tuple’s, we have Tuple{UnitRange{Int64}} <: Tuple{AbstractArray}
, the first command makes sense. However, in the second and even the third command, the type Tuple{AbstractArray}
appears, and only the fourth command will behave analogously to the first command. The fifth changes in turn the eltype
of UnitRange
to Any
, which is somewhat what the second command does, but now for the eltype
.
Secondly, there is also some trouble with Vector
’s of NamedTuple
’s, while for Tuple
’s, types are automatically derived. Is this intended or maybe just not (yet) implemented?
typeof([(1:2,), ([1, 2],)]))
# Vector{Tuple{AbstractVector{Int64}}} (case 2.1)
typeof([(a=1:2,), (a=1:2,)])
# Vector{NamedTuple{(:a,), Tuple{UnitRange{Int64}}}} (case 2.2)
typeof([(a=1:2,), (a=[1, 2],)])
# Vector{NamedTuple{(:a,)}} (case 2.3)
Though one can manually convert the latter Vector
, this becomes increasingly cumbersome due to the first issue:
typeof(convert(Vector{NamedTuple{(:a,),Tuple{AbstractArray}}}, [(a=1:2,), (a=[1, 2],)]))
# Vector{NamedTuple{(:a,), Tuple{AbstractArray}}} (case 3.1)
typeof(convert(Vector{NamedTuple{(:a,),<:Tuple{AbstractArray}}}, [(a=1:2,), (a=[1, 2],)]))
# Vector{NamedTuple{(:a,), <:Tuple{T} where T<:AbstractArray}} (case 3.2)
typeof(convert(Vector{NamedTuple{(:a,),<:Tuple{AbstractArray{Int64}}}}, [(a=1:2,), (a=[1, 2],)]))
# Vector{NamedTuple{(:a,), <:Tuple{AbstractArray{Int64}}}} (case 3.3)
Thirdly, when one in turn includes an abstract eltype Number
, an error may be thrown. I have included some more commands for better reference, while the error is thrown by the last command.
typeof(convert(Tuple{AbstractArray{<:Number}}, (1:2,)))
# Tuple{UnitRange{Int64}} (case 4.1)
typeof(convert(Tuple{AbstractArray{Number}}, (1:2,)))
# Tuple{Vector{Number}} (case 4.2)
typeof(convert(NamedTuple{(:a,),Tuple{AbstractArray{<:Number}}}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{AbstractArray{<:Number}}} (case 4.3)
typeof(convert(NamedTuple{(:a,),Tuple{AbstractArray{Number}}}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{AbstractArray{Number}}}((Number[1, 2],)) (case 4.4)
typeof(convert(NamedTuple{(:a,),<:Tuple{AbstractArray{<:Number}}}, (a=1:2,)))
# NamedTuple{(:a,), Tuple{UnitRange{Int64}}} (case 4.5)
convert( NamedTuple{(:a,),<:Tuple{AbstractArray{Number}}}, (a=1:2,))
# throws error (case 4.6)