# Constructors for `UnionAll` types

I have a simple type with two parameters, something like

``````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> (::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> 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> (::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

``````(::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.

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

``````(::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

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

1 Like

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.