How to get the container type of a container?

For example, I have an x = Vector{Int}, then do what operations on x can I get the Vector?

1 Like

If you want to get Array from Vector{Int}, I’ve been using

constructor_of(::Type{T}) where T =
    getfield(T.name.module, Symbol(T.name.name))

since Julia 0.6 for this purpose. If you only target 1.x, I think

constructor_of(::Type{T}) where T =
    getfield(parentmodule(T), Symbol(Base.typename(T)))

may be better.

But getting Vector from Vector{Int} seems harder because Vector{Int} actually is Array{Int,1}.

If you need to special-case only a few types, you can add a method to constructor_of:

constructor_of(::Type{T}) where {T <: Vector} = Vector
1 Like

I’m not sure exactly what you’re asking here.

Do you have a vector instance (eg, x = [1,2,3]) and you want to get the type? You can use typeof(x) for that.

Do you have a vector instance x and want to create another vector y which is the same shape and type? Use similar(x) for that.

1 Like

Sorry, I should be more clear. I am writing a pseudo-code here because it is not a valid syntax in Julia:

julia> f(x::T{Int}) where {T <: AbstractArray} = convert(T{Float64}, x)
ERROR: TypeError: in Type{...} expression, expected UnionAll, got TypeVar

i.e., f eats an AbstractArray of something (Int here), and converts it to an AbstractArray of another thing (Float64 here). However, Julia does not allow TypeVar in the function definition. I know I can use map in such simple case, but what I am actually facing is a bit more complicated that this example so I feel hard to write map.

I am not sure it would work in general, since convert does not need to be defined for a type to implement the AbstractArray interface. Eg

struct MyArray{T, N, A <: AbstractArray{T,N}} <: AbstractArray{T,N}
    parent::A
end

Base.size(A::MyArray) = size(A.parent)
Base.getindex(A::MyArray, I...) = getindex(A.parent, I...)

A = rand(Int,3,3)
B = MyArray(A)
convert(MyArray{Float64}, B)    # will error

If I understand correctly, you want to strip the type parameters from a type. That is not possible in general Stripping parameter from parametric types. similar is made for this.

3 Likes

Yes, you are right. That’s what I want!