abstract type MM{T} end
capture(::Type{MM{T}}) where T = T
capture(MM{Int})
Int64
julia> const CMM{C} = MM{T} where T<:C
MM{T} where T<:C where C
julia> capture(::Type{CMM{T}}) where T = T
capture (generic function with 2 methods)
julia> capture(CMM{Int})
ERROR: UndefVarError: T not defined
Stacktrace:
[1] capture(::Type{MM{T} where T<:Int64}) at ./REPL[5]:1
[2] top-level scope at REPL[6]:1
The second one doesn’t work? Is there a way to capture Int in the second example?
I think an interesting aspect is that this still happens when C is Int which is a concrete type. Shouldn’t upper-bounding by a concrete type determine the type parameter? The reason that it’s not enough is Union{} <: Int. Because of this, we have:
julia> abstract type MM{T} end
julia> CMM{C} = MM{T} where T<:C
MM{T} where T<:C where C
julia> MM{Int} <: CMM{Int}
true
julia> MM{Union{}} <: CMM{Int}
true
So, julia can’t decide what T in MM{T} where T<:C should be.