NamedTuples in Type Constructors


I’m trying to do some type constructing with NamedTuple fields in 0.7beta. Here’s my problem:

julia> struct MyStruct x::NamedTuple{(:a,:b), Tuple{Real,Real}} end

julia> MyStruct(x::NamedTuple{(:b,), Tuple{Real,}}) = MyStruct((a=1, b=x[:b]))

julia> MyStruct((a=1, b=3))
MyStruct(NamedTuple{(:a, :b),Tuple{Real,Real}}((1, 3)))

julia> s = MyStruct((b=3,))
ERROR: MethodError: Cannot `convert` an object of type NamedTuple{(:b,),Tuple{Int64}} to an object of type NamedTuple{(:a, :b),Tuple{Real,Real}}
Closest candidates are:
  convert(::Type{NamedTuple{names,T<:Tuple}}, ::NamedTuple{names,T<:Tuple}) where {names, T<:Tuple} at namedtuple.jl:107
  convert(::Type{NamedTuple{names,T<:Tuple}}, ::NamedTuple{names,T} where T<:Tuple) where {names, T<:Tuple} at namedtuple.jl:111
  convert(::Type{T}, ::T) where T at essentials.jl:123
 [1] MyStruct(::NamedTuple{(:b,),Tuple{Int64}}) at ./REPL[32]:1
 [2] top-level scope at none:0

I really don’t get why this should throw an error.

I think you want something l like

MyStruct(x::NamedTuple{(:b,), T}) where {T <: Tuple{Real,}} =
    MyStruct((a=1, b=x[:b]))

also note that

julia> (b=3,) isa NamedTuple{(:b,), Tuple{Real,}}

julia> (b=3,) isa NamedTuple{(:b,), <:Tuple{Real,}}

This explanation may help.

Also, for similar reasons, you may want to avoid structs with abstract typed fields, and use

struct MyStruct{T <: Tuple{Real,Real}}
    x::NamedTuple{(:a,:b), T}