Problems with dispatching of Base.iterate

It’s not different–those method definitions are exactly the same:

julia> abstract type A end

julia> f(x::A) = 1
f (generic function with 1 method)

julia> f(x::T) where {T <: A} = 2
f (generic function with 1 method)

Note how f still has exactly one method, because A and T where T <: A are exactly identical:

julia> (T where T <: A) === A
true

Reading between the lines in your example, I wonder if you were actually doing something like:

julia> struct Container{T}; end

julia> g(x::Container{A}) = 1
g (generic function with 1 method)

vs.

julia> g(x::Container{T}) where {T <: A} = 2
g (generic function with 2 methods)

Because parametric types in Julia are not covariant, Container{A} and Container{T} where {T <: A} are indeed different.

This comes up often in arrays, since an Array{Real} is an array in which each element can be any (different) kind of Real, while an Array{T} where {T <: Real} is an array with an element type which is itself some subtype of Real. Thus, Array{Int} is a subtype of Array{T} where {T <: Real}, but Array{Int} is not a subtype of Array{Real}. Invariance can be hard to wrap your head around the first time–I had to read this section of the manual a few times before I got it: Types · The Julia Language

1 Like