@generated function (m::ProductModel{<:NamedTuple{MS}})(ds::ProductNode{<:NamedTuple{DS}}) where {MS, DS}
@assert MS ⊂ DS
vals = [:(Core.getfield(m.ms, $(QuoteNode(k)))(Core.getfield(ds.data, $(QuoteNode(k))))) for k in MS]
:(m.m(vcat($(vals...))))
end
First try