Constrain type to be concrete subtype

Suppose I have the following struct:

struct Foo{T <: Real}
    a::T
end

I am still able to construct a Foo as: Foo{Real}(20). Is there a way to demand that the type parameter be a concrete type such as Int64, Float64, etc.

I know I could use isconcretetype in a constructor to meet that demand, but is that the only way. Is there any way to do it directly in the constraint of the type parameter?

No, since every type is also its own subtype. Dispatching on whether or not something is concrete is not possible.

Checking and throwing in the constructor is the only solution I know of, but usually not necessary.

2 Likes

Supplying a type parameter is something you normally do only if you want a different type than that of the input value, like e.g. an abstract supertype.

You can instead just call the constructor like Foo(20), and that will return a Foo{Int}.

I understand that, I just wanted to make it an error to try to do so. So that I and others couldn’t make a mistake that could lead to a runtime error (methods only defined for concrete types later on somewhere else) or performance issues.

But using a constructor for such validation is fine for my use case. I was just asking if there was a different way out of curiosity.