MWE:
julia> abstract type MyType{T} <: Any end
julia> struct myT1{T} <: MyType{T}
a::T
end
julia> struct myT2{T} <: MyType{T}
a::T
end
julia> getBuilder(a::MyType) = getfield(Main, (nameof∘typeof)(a))
getBuilder (generic function with 1 method)
julia> m1 = myT1(1.3)
myT1{Float64}(1.3)
julia> m2 = myT2(1.4)
myT2{Float64}(1.4)
julia> getBuilder(m1) == myT1
true
julia> getBuilder(m2) == myT2
true
Is there a better solution than how getBuilder
is currently defined? Thanks!
1 Like
Maybe getBuilder(a::T{<:Any}) where {T<:MyType}=T
?
I don’t think this is the sort of thing that you generally should be doing. Can you tell us the higher level goal? We might be able to suggest a better pattern.
2 Likes
If I understand correctly, the general consensus is that it is “hacky” and you shouldn’t do it. See Search results for 'strip type parameters' - Julia Programming Language
If you own the types, you could just do
myBuilder(::myT1) = myT1
myBuilder(::myT2) = myT2
If you have many types, you could achieve the same with less typing with metaprogramming, i.e. maybe something like
for op ∈ (:myT1, :myT2)
eval(quote
getBuilder(::$op) = $op
end)
end
1 Like
This was discussed a little while ago in this thread: Is there a way to get a UnionAll base type from a concrete type?
One good way seems to be to use the package ConstructionBase.jl, and write
using ConstructionBase
m1 = myT1(1.0)
constructorof(typeof(m1)) # myT1
It’s not defined for instances, but you could define
builder(x::Type) = constructorof(x)
builder(x) = builder(typeof(x))
2 Likes