# UndefVarError for Type Variable

I’m sure I’m missing something obvious, but here we go. I defined methods that dispatch on the type of various “special matrices” from LinearAlgebra. Here is a MWE:

``````using LinearAlgebra

for type ∈ [:Symmetric, :LowerTriangular]
@eval f(::Type{\$type{T}}) where T = T
end
``````

The expected result is returned when called on type `LowerTriangular`:

``````julia> f(LowerTriangular{Float64})
Float64
``````

However, when called on `Symmetric`, I get:

``````julia> f(Symmetric{Float64})
ERROR: UndefVarError: T not defined
Stacktrace:
 f(#unused#::Type{Symmetric{Float64, S} where S<:(AbstractMatrix{<:Float64})})
@ Main ./REPL:2
 top-level scope
@ REPL:1
``````

Interestingly, the following implementation works:

``````f(::Type{Symmetric{T, S}}) where {T, S} = T

julia> f(Symmetric{Float64, Matrix{Float64}})
Float64
``````

Any idea?

Fully specifying the type vars works for me

``````using LinearAlgebra

for type ∈ [:Symmetric, :LowerTriangular]
@eval f(::Type{\$type{T, A}}) where {T, A} = T
end

@show f(LowerTriangular{Float64,Matrix{Float64}})
@show f(Symmetric{Float64,Matrix{Float64}})
``````

yielding

``````f(LowerTriangular{Float64, Matrix{Float64}}) = Float64
f(Symmetric{Float64, Matrix{Float64}}) = Float64
``````

Don’t know if this helps though.

Yeah that works for me too. I just don’t understand how I can partially specify it for one type and not for the other.

I understand my job here as to make things work, sometimes without understanding why. So let us ask another question. What might be the sense of

``````@show LowerTriangular{Float32,Matrix{Float64}}([[1, 2], [3, 4], [5, 6]])
``````

``````ERROR: LoadError: TypeError: in LowerTriangular, in S, expected S<:AbstractMatrix{Float32}, got Type{Matrix{Float64}}
``````

So maybe this was designed before the invention of `eltype`?

This is simply due to the definition of `LowerTriangular`: here

But at least syntactically

``````abstract type MyAbstractTriangular{S<:AbstractMatrix} <: AbstractMatrix{eltype(S)} end
``````

is accepted.

Edit: this seems to work, too:

``````struct MyTriangularMatrix{S<:AbstractMatrix} <: MyAbstractTriangular{S}
A::S
end

function MyTriangularMatrix{T}(A::Matrix{T}) where T
end

tr = MyTriangularMatrix([(1, 2) (3, 4) (5, 6)])
println()
``````

This might be an implementation detail? What are you more interested in: this detail or the general idea?