Dispatch on NamedTuple

Hi,

I was wondering if there is a way to dispatch on NamedTuple function arguments based on the types used within the NamedTuple without knowing the number of elements inside but with all elements having the same type.

So I would like to do something like this below:

function foo(nt::NamedTuple{Symbol, MyType})
	println("The argument is a NamedTuple containing MyType elements")
end
	
function foo(nt::NamedTuple{Symbol, AnotherMyType})
	println("The argument is a NamedTuple containing AnotherMyType elements")
end

So that

nt = (a = MyType(5), b = MyType(6), c = MyType(55))
nt2 = (x = AnotherMyType(2), y = AnotherMyType(3))

foo(nt)
The argument is a NamedTuple containing MyType elements

foot(nt2)
The argument is a NamedTuple containing AnotherMyType elements

Is there a better way to achieve this than doing something like this:

function foo(nt::NamedTuple)

	if isa(foo[1], MyType) 
		println("The argument is a NamedTuple containing MyType elements")
		
	elseif isa(foo[1], AnotherMyType) 
		println("The argument is a NamedTuple containing AnotherMyType elements")
	end
	
end
1 Like

Sure, the type of the ordinary tuple is part of the type of the named tuple:

julia> typeof((a=1, b=2))
NamedTuple{(:a, :b),Tuple{Int64,Int64}}

julia> ans <: NamedTuple{<:Any, <:Tuple{Vararg{Int}}}
true

julia> (a=1, b=2, c=3) isa NamedTuple{<:Any, <:Tuple{Vararg{Int}}}
true
4 Likes

Ah, thanks a lot! The Vararg is what I was missing.

Using a NTuple instead of Vararg, you can also get the number of elements if it matters to you:

julia> function foo(nt::NamedTuple{<:Any, NTuple{N, T}}) where {N, T}
           "Argument is a NamedTuple containing $N elements of type $T"
       end
foo (generic function with 1 method)

julia> foo((x=1, y=1))
"Argument is a NamedTuple containing 2 elements of type Int64"
5 Likes