Type of type parameters


Sometimes I wish I could express that the parameters of a certain parametrised struct must be of a certain type. For example, I would like to have syntax that allows

struct ContinuousShift{s::Real} <: AbstractSymmetry end

to mean that the parameter s will be a real number, or maybe

struct DiscreteShift{m::Int} <: AbstractSymmetry end

for when only integers would make sense. I can live without this, but I think other people might have wanted this kind of ability at some point.


Is this: struct ContinuousShift{s<:Real} <: AbstractSymmetry end not what you want?


I agree that that syntax would be nice. The closest I’ve found is:

julia> struct Foo{N}
         Foo{N}(x) where {N} = new{typeassert(N, Integer)}(x)

julia> Foo{3}(1)

julia> Foo{3.5}(1)
ERROR: TypeError: Type: in typeassert, expected Integer, got Float64
 [1] Foo{3.5}(::Int64) at ./REPL[1]:3


He wants s to be an instance of Real, not a subtype of Real. It’s not currently supported. See e.g. https://github.com/JuliaLang/julia/issues/9580#issuecomment-101408507.


FWIW, I think if this were to be implemented, I think

struct DiscreteShift{m isa Int} <: AbstractSymmetry end

would be more consistent than

struct DiscreteShift{m::Int} <: AbstractSymmetry end

because outside of type definitions m<:Foo returns a boolean, whereas m::Int is a type assertion, as noted in @yuyichao’s comment, and m isa Int would also return a boolean.


This syntax would be closer to method definitions, though.