Type Reconstruction Question

Hi,

Let’s assume that I have the following definition

julia>abstract type Foo{T,U} end

julia> typ = Foo{Int,Float64}
Foo{Int64,Float64}

julia> typ.parameters
svec(Int64, Float64)

#this is the function I would like to write
julia>reconstruct_params(typ,(Float64,Float64))
Foo{Float64,Float64}

How can I write the “reconstruct_params” function? How can I manipulate types at runtime?

Thanks

I think this is the same as was just asked:

1 Like
function reconstruct_params(::Type{T}, ::Type{U}, ::Type{V}) where {T,U,V}
    return T{U,V}
end

or,

@generated function reconstruct_params(::Type{T}, ::Type{U}, ::Type{V}) where {T,U,V}
    return :(T{U,V})
end

Both versions work with

reconstruct_params(Foo, Float64, Float64)

But not with

julia> reconstruct_params(Foo{Int,Int}, Float64, Float64)
ERROR: TypeError: in Type{...} expression, expected UnionAll, got Type{Foo{Int64,Int64}}
Stacktrace:
 [1] reconstruct_params(::Type{Foo{Int64,Int64}}, ::Type{Float64}, ::Type{Float64}) at ./REPL[1]:2
 [2] top-level scope at none:0

which is the OP’s question.

function reconstruct_params(::Type{Foo{S,T}}, ::Type{U}, ::Type{V}) where {S,T,U,V}
    return Foo{U,V}
end
1 Like

(Note though that this doesn’t extent to subtypes of Foo, which is what above link is about.)

What if I want to do this on general scale,
What if I wouldn’t know the type and the number of parameters it is taking.

Thanks

What actual problem are you trying to solve? Probably there is a better way to do it … it seems like you are fighting with the language to do something in a non-idiomatic way.

1 Like

That’s what’s discussed in the link I posted. Maybe read that and then report back.

1 Like

One can easily overload the function for that.

Sure, but in general you have to do it for each subtype, which is essentially what similar does for arrays (plus it also instantiates the type).

1 Like
julia> abstract type Foo{T,U} end
julia> Base.@pure reconstruct_params(::Type{T}, ::Type{P1},::Type{P2}) where {T,P1,P2}=T.name.wrapper{P1,P2}
julia> typ = Foo{String, Int}
Foo{String,Int64}
julia> reconstruct_params(typ, UInt8, Float32)
Foo{UInt8,Float32}