# Better way to get the corresponding constructor from composite-type instances?

**URL:** <https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661>\
**Category:** General Usage\
**Tags:** parametric-types, constructors\
**Created:** [November 15, 2024, 12:09am UTC](https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661 "2024-11-15T00:09:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![frankwswang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankwswang/32/18561_2.png) [@frankwswang](https://discourse.julialang.org/u/frankwswang)\
**Post date:** [November 15, 2024, 12:09am UTC](https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661/1 "2024-11-15T00:09:57Z")

</div>

MWE:

```julia
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!

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [November 15, 2024, 12:38am UTC](https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661/2 "2024-11-15T00:38:07Z")

</div>

Maybe `getBuilder(a::T{<:Any}) where {T<:MyType}=T`?

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [November 15, 2024, 1:36am UTC](https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661/3 "2024-11-15T01:36:31Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![abraunst](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraunst/32/6880_2.png) [@abraunst](https://discourse.julialang.org/u/abraunst)\
**Post date:** [November 15, 2024, 10:14am UTC](https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661/4 "2024-11-15T10:14:23Z")

</div>

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](https://discourse.julialang.org/search?q=strip%20type%20parameters)

If you own the types, you could just do

```julia
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

```julia
for op ∈ (:myT1, :myT2)
           eval(quote
               getBuilder(::$op) = $op
           end)
       end

```

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [November 15, 2024, 3:27pm UTC](https://discourse.julialang.org/t/better-way-to-get-the-corresponding-constructor-from-composite-type-instances/122661/5 "2024-11-15T15:27:25Z")

</div>

This was discussed a little while ago in this thread: [Is there a way to get a UnionAll base type from a concrete type?](https://discourse.julialang.org/t/is-there-a-way-to-get-a-unionall-base-type-from-a-concrete-type/122328)

One good way seems to be to use the package ConstructionBase.jl, and write

```julia
using ConstructionBase
m1 = myT1(1.0)
constructorof(typeof(m1)) # myT1

```

It’s not defined for instances, but you could define

```julia
builder(x::Type) = constructorof(x)
builder(x) = builder(typeof(x))

```
