Capturing a parameter of a type!

abstract type MM{T} end

capture(::Type{MM{T}}) where T = T


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
 [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?


To me the error makes sense. Note that the problem is not in “capturing” the type, but rather the definition of CMM: in

const CMM{C} = MM{T} where T<:C

what type is T supposed to be?

1 Like

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}

julia> MM{Union{}} <: CMM{Int}

So, julia can’t decide what T in MM{T} where T<:C should be.

This just caused an “interesting” bug in StaticArrays: See also:

1 Like