I would like to create a struct that holds a subtype of Real, which I want to use later on to create buffer arrays. I managed to do that in the MWE below, but it seems like the corresponding struct is not a concrete type. Is there anything I can do to alleviate that?
struct TypeHolder{T<:Real}
type :: Type{T}
function TypeHolder(type::Type{T}) where {T<:Real}
return new{T}(type)
end
end
holder = TypeHolder(Float16) #TypeHolder{Float16}
isconcretetype(holder) #false
I get an error with your code because your inner constructor is called TypeHolder2 instead of TypeHolder. If I rename it, then I get what you want if you pass the type of holder to isconcretetype:
First, you should use isconcretetype on types such as TypeHolder{Float16}, not values (such as holder in your example):
isconcretetype(typeof(holder)) # true
but then this does not give you much information: by definition of what a concrete type is, the type of holder will always be concrete (since there exists a value, holder, having this type).
I’m actually not sure of what exactly you’re trying to achieve here, but there’s probably no need to store the type as a field in the struct: having it as a type parameter makes it possible to retrieve it when you need it. A minimal example could look like:
struct TypeHolder{T<:Real}
function TypeHolder(::Type{T}) where {T<:Real}
return new{T}()
end
end
holder = TypeHolder(Float16) # TypeHolder{Float16}
isconcretetype(typeof(holder)) # true (by definition)
# a function that needs to know about T in order to build a buffer
function compute(x::TypeHolder{T}) where {T}
buffer = Vector{T}(undef, 10)
do_something_with(buffer)
end