# Constructors for \`UnionAll\` types

**URL:** <https://discourse.julialang.org/t/constructors-for-unionall-types/41999>\
**Category:** General Usage\
**Tags:** question, parametric-types\
**Created:** [June 24, 2020, 5:11pm UTC](https://discourse.julialang.org/t/constructors-for-unionall-types/41999 "2020-06-24T17:11:00Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mhauru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhauru/32/208880_2.png) [@mhauru](https://discourse.julialang.org/u/mhauru)\
**Post date:** [June 24, 2020, 5:11pm UTC](https://discourse.julialang.org/t/constructors-for-unionall-types/41999/1 "2020-06-24T17:11:00Z")

</div>

I have a simple type with two parameters, something like

```julia
julia> struct Thingy{N, T}
           a::NTuple{N, T}
       end

```

and I try to define the following constructors for it, where the second parameter is fixed:

```julia
julia> (::Type{(Thingy{N, Float64} where N)})(n::NTuple{N, Float64}) where {N} = Thingy{N, Float64}(n)
ERROR: syntax: invalid variable expression in "where"

```

On the other hand, if I just take that `UnionAll` expression from within `Type{}` and attach it to a variable:

```julia
julia> FloatThingy{N} = Thingy{N, Float64} where N
Thingy{N,Float64} where N

julia> (Thingy{N, Float64} where N) === FloatThingy
true

```

then the same kind of constructor works just fine:

```julia
julia> (::Type{FloatThingy})(n::NTuple{N, Float64}) where {N} = Thingy{N, Float64}(n)

julia> FloatThingy((0.1, 0.2))
Thingy{2,Float64}((0.1, 0.2))

```

This leaves me with the impression that constructors are really attached to names like `FloatThingy`, rather than the type itself. But on the other hand, the whole `(::Type{T})(blahblah)` syntax for constructors seems to suggest otherwise. So how do I understand what’s happening here?

Also, the reason I ran into this is that I’m trying to create constructors of the form

```julia
(::Type{(Thingy{N, T} where N)})(n::NTuple{N, T}) where {N} 

```

for all `T`, so that I can later define things like `FloatThingy` and similarly `IntThingy` and `SymbolThingy` and whatnot, and have the constructors work without defining them for each subtype individually. If someone can direct me towards a way of achieving this, then gratefulness is on offer.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 25, 2020, 9:19am UTC](https://discourse.julialang.org/t/constructors-for-unionall-types/41999/2 "2020-06-25T09:19:48Z")

</div>

> [@mhauru](#):
>
> This leaves me with the impression that constructors are really attached to names like `FloatThingy` , rather than the type itself.

This impression is mistaken — the problem is that you are using `N` for two things in a nested way, which is not allowed (how would Julia know which is which?). Try eg (note the `K`)

```julia
(::Type{(Thingy{K, Float64} where K)})(n::NTuple{N, Float64}) where {N} = Thingy{N, Float64}(n)

```

That said, I would just reverse the order of type parameters, and then you could shorten this code to something like

```julia
Thingy{Float64}(n::NTuple{N, Float64}) where N = ...

```

The order of type parameters is very useful for specifying unionall types like this, to the extend that it is worth defining aliases with different orders — `NTuple` is one of those.

---

<div class="post-metadata">

**Author:** ![mhauru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhauru/32/208880_2.png) [@mhauru](https://discourse.julialang.org/u/mhauru)\
**Post date:** [June 25, 2020, 9:44am UTC](https://discourse.julialang.org/t/constructors-for-unionall-types/41999/3 "2020-06-25T09:44:14Z")

</div>

Thanks! I guess I should have paid more attention to the actual error message Julia gave me, rather than assume there was something deeper going on.
