Type of type parameters


#1

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.


#2

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


#3

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

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

julia> Foo{3}(1)
Foo{3}(1)

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


#4

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.


#5

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.


#6

This syntax would be closer to method definitions, though.