Type Reconstruction Question

#1

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

#2

I think this is the same as was just asked:

1 Like
#3
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)
#4

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.

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

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

#7

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

#8

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
#9

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

1 Like
#10

One can easily overload the function for that.

#11

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
#12
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}