Question:
One correct and two wrong code templates for extracting the type parameter from a super-type is provided in this subsection of the manual. I don’t understand how the “correct template” doesn’t fail for the argument that is given as an example where the (second) “wrong template” might fail, and would appreciate if someone can help me grasp it. Thank you!
Details:
(From the manual subsection) The abstract type
definition and the correct template is:
abstract type AbstractArray{T, N} end
eltype(::Type{<:AbstractArray{T}}) where {T} = T
And the (second) wrong template is:
eltype_wrong(::Type{AbstractArray{T}}) where {T} = T
eltype_wrong(::Type{AbstractArray{T, N}}) where {T, N} = T
eltype_wrong(::Type{A}) where {A<:AbstractArray} = eltype_wrong(supertype(A))
Now the manual gives an example where this wrong approach fails:
julia> eltype_wrong(Union{AbstractArray{Int}, AbstractArray{Float64}})
ERROR: MethodError: no method matching supertype(::Type{Union{AbstractArray{Float64,N} where N, AbstractArray{Int64,N} where N}})
Closest candidates are:
supertype(::DataType) at operators.jl:43
supertype(::UnionAll) at operators.jl:48
but also the “correct” code template fails when I call it with the same argument (or falls back to Base.eltype
, but the same holds if we rename the “wrong” code template):
julia> eltype(Union{AbstractArray{Int}, AbstractArray{Float64}})
ERROR: MethodError: no method matching eltype(::Type{Union{AbstractArray{Float64}, AbstractArray{Int64}}})
You may have intended to import Base.eltype
Closest candidates are:
eltype(::Type{<:AbstractArray{T}}) where T at REPL[9]:1
Stacktrace:
[1] top-level scope
@ REPL[31]:1
It doesn’t say explicitly that the “correct template” should work for these arguments, but since it is given to justify why the alternative is wrong, I take it as implied. And of course there are other reasons why the “correct template” is preferred, but I would like to understand the reason given in the manual.