Let
julia> using LinearAlgebra
julia> id(X,T) = T(Matrix{eltype(X)}(I, size(X)...))
id (generic function with 1 method)
julia> A = complex.(randn(2,2),randn(2,2));
julia> typeof(transpose(id(A,Hermitian)))
Transpose{ComplexF64, Hermitian{ComplexF64, Matrix{ComplexF64}}}
Now, we define two functions as follows:
julia> f(A::Transpose{T,Hermitian{T,M}}) where {T,M <: StridedMatrix} = 1
f (generic function with 1 method)
julia> methods(f)
# 1 method for generic function "f" from Main:
[1] f(A::Transpose{T, Hermitian{T, M}}) where {T, M<:(StridedMatrix{T} where T)}
@ REPL[5]:1
julia> g(A::Transpose{T,Hermitian{T, <:StridedMatrix}}) where {T} = 1
g (generic function with 1 method)
julia> methods(g)
# 1 method for generic function "g" from Main:
[1] g(A::Transpose{T, Hermitian{T, <:StridedMatrix{T} where T}}) where T
@ REPL[7]:1
I would expect both functions to accept a variable of type transpose(id(A,Hermitian))
. However, f
works and g
does not!
julia> f(transpose(id(A,Hermitian)))
1
julia> g(transpose(id(A,Hermitian)))
ERROR: MethodError: no method matching g(::Transpose{ComplexF64, Hermitian{ComplexF64, Matrix{ComplexF64}}})
Closest candidates are:
g(::Transpose{T, Hermitian{T, <:StridedMatrix{T} where T}}) where T
@ Main REPL[7]:1
Stacktrace:
[1] top-level scope
@ REPL[10]:1
Could someone please explain why this is the case? That is, why must M
be explicitly declared here although the method signatures seem equivalent.