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
mauro3
April 12, 2019, 6:44pm
2
I think this is the same as was just asked:
I would like to dispatch a method like this, where T gets the type <: AbstractParticles and the type parameters end up in F and NT.
function Base.union(p1::T{F,NT},p2::S{F,NS}) where T <: AbstractParticles where S <: AbstractParticles{F,NS} where F where NT where NS
T{F,NT+NS}([p1.particles; p2.particles])
end
This does not work and an error
TypeError: in Type{...} expression, expected UnionAll, got TypeVar
occurs. The following definition is accepted, but it makes T include the type par…
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)
mauro3
April 12, 2019, 10:59pm
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.
function reconstruct_params(::Type{Foo{S,T}}, ::Type{U}, ::Type{V}) where {S,T,U,V}
return Foo{U,V}
end
1 Like
mauro3
April 12, 2019, 11:32pm
6
(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
mauro3
April 13, 2019, 6:48am
9
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.
mauro3
April 13, 2019, 11:47am
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
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}