# Abstract parametric constructors

**URL:** <https://discourse.julialang.org/t/abstract-parametric-constructors/57387>\
**Category:** General Usage\
**Created:** [March 17, 2021, 2:10pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387 "2021-03-17T14:10:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 17, 2021, 2:10pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387/1 "2021-03-17T14:10:00Z")

</div>

How can I create a constructor for a parametric type using its abstract supertype?  
This is my minimal nonworking example 😉

```julia
abstract type MyNumber{T1<:Integer,T2<:Integer} end

struct MyNumber1{T1,T2} <: MyNumber{T1,T2}
    a :: T1
    b :: T2
end

struct MyNumber2{T1,T2} <: MyNumber{T1,T2}
    a :: T1
    b :: T2
end

function (::Type{MT})(a::T1,b) where {T1 <: Integer, MT<:MyNumber{T1}}
    println("here?")
end

MyNumber1{Int}(1,2)

```

the error message is:

```julia
julia> MyNumber1{Int}(1,2)
ERROR: MethodError: no method matching (MyNumber1{Int64, T2} where T2)(::Int64, ::Int64)
Stacktrace:
[1] top-level scope
  @ REPL[10]:1

```

if I write it as a Union like:

```julia
function (::Type{MT})(a::T1,b) where {T1 <: Integer, MT<:Union{MyNumber1{T1}, MyNumber2{T1}}}
    println("here?")
end

```

it works though.  
Appreciate any help and explanation why this doesn’t work.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 17, 2021, 2:20pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387/2 "2021-03-17T14:20:35Z")

</div>

I do not know the explanation, but this works

```julia
function (::Type{MT})(a::T1,b) where {T1 <: Integer, MT<:MyNumber{T1, T2} where T2}
    println("here?")
end

```

Also

```julia
julia> (MyNumber1{Int64, T2} where T2) <: MyNumber{Int64}
false

julia> (MyNumber1{Int64, T2} where T2) <: (MyNumber{Int64, T3} where T3)
true

```

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 17, 2021, 2:27pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387/3 "2021-03-17T14:27:57Z")

</div>

Thanks a lot. I’ve never seen a `where` inside a `where` before 😄  
I was wondering why I need to specify all of the types of the parametric type (so T1 and T2) in general.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 17, 2021, 2:29pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387/4 "2021-03-17T14:29:22Z")

</div>

I guess it’s called triangular dispatch and it was a big deal around 0.5 or 0.6

As for your second question, someone with deeper understanding should come in here.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [March 17, 2021, 2:31pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387/5 "2021-03-17T14:31:21Z")

</div>

You can just skip the the type signature:

```julia
julia> abstract type MyNumber{T1<:Integer,T2<:Integer} end

julia> struct MyNumber1{T1,T2} <: MyNumber{T1,T2}
           a :: T1
           b :: T2
       end

julia> MyNumber1(1,2)
MyNumber1{Int64,Int64}(1, 2)

```

edit: I see that the definition of that function complicates things, sorry.

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 17, 2021, 2:35pm UTC](https://discourse.julialang.org/t/abstract-parametric-constructors/57387/6 "2021-03-17T14:35:04Z")

</div>

Sorry my example is a bit contrived. In my actual example I have some parts in the parametric fields (don’t know how to call them 😃 ) which can’t be extracted from the values of the function. Therefore I need to give `T1` but `T2` can be taken from the input. Hope that makes sense.
