Understanding generic functions and parametric types

Hello all,

I’m new to Julia and I’m trying to understand how type deduction works for generic functions with parametric types. To test my hands at things, I tried to define a function that takes one argument that should be a vector-like of tuples with two elements, a numeric matrix-like and a string. So I tried the following:

f(::AbstractVector{Tuple{AbstractMatrix{T},String}}) where T<:Number = @show T

I then defined a matrix a

a = [ 11 12 13 ; 21 22 23 ]

and expected f( [(a, "a")] ) to be equivalent to @show Int64, but instead got the error:

julia> f( [ (a, "a") ])
ERROR: MethodError: no method matching f(::Vector{Tuple{Matrix{Int64}, String}})

Closest candidates are:
  f(::AbstractArray{Tuple{AbstractMatrix{T}, String}, 1}) where T<:Number

So what am I missing?

1 Like

Hi there! If we take things step by step to check subtyping, we’ll see what went wrong:

julia> a isa AbstractMatrix
true

julia> (a, "a") isa Tuple{AbstractMatrix, String}
true

julia> [(a, "a")] isa AbstractArray{Tuple{AbstractMatrix, String}}
false

julia> [(a, "a")] isa AbstractArray{<:Tuple{AbstractMatrix, String}}
true

The problem here is that just because two types satisfy T1 <: T2 doesn’t mean AbstractArray{T1} <: AbstractArray{T2}. The section of the docs explaining this is Parametric Composite Types.
Note that the behavior of Tuple is different from that of other parametric types, which is something I always struggle to remember.

1 Like

Thank you very much!

I had already gone through the Types and More about types pages in the docs, but it’s a lot to digest, so I missed that particular aspect. The fact that when testing with tuples it hadn’t tripped didn’t help indeed :wink:

I’ve gone with AbstractVector{Tuple{M,String}} where M <: AbstractMatrix{<:Number}, but now I’ve got a related problem for “diagonal types”, if my understanding is correct. I’ll open a new topic for it. Thanks again.

2 Likes

You might also find the in-development version of the <: doc string useful.

1 Like