# How to make a particular NTuple based Type concrete

I have a struct representing the remainders of an integer with respect to several moduli. All of the moduli fit into `Int64` except for `2^64`, so every modulus is either an `Int64` or `Type{Int64}`.

``````struct LooseGoose{N}
remainders::NTuple{N,Int64}
moduli::NTuple{N,Union{DataType,Int64}}
end
import Base: *
*(g::LooseGoose, r::Int64) = LooseGoose( mod.( widen.(g.remainders) .* r , g.moduli) .|> Int64 , g.moduli )
LooseGoose((4,7,12),(Int64,11,17)) * 7
``````

This works fine, except in practice I always want the first modulus to be `Int64` and the remaining moduli to be numeric. Is there a convenient way to specify this in the type definition without the `Union`. I can enforce this in a constructor.

``````struct StrictGoose{N}
remainders::NTuple{N,Int64}
moduli::NTuple{N,Union{DataType,Int64}}

function StrictGoose(remainders::NTuple{N,Int64}, moduli) where {N}
moduli isa Tuple{DataType, (Int64 for i=2:N)...} || throw(ArguementError("moduli of incorrect form"))
new{N}(remainders,moduli)
end
end
StrictGoose((4,7,12),(Int64,11,17)) # Succeeds
StrictGoose((4,7,12),(13,Int64,17)) # Throws an error
``````
1. Is there a way to eliminate the `Union` and specify `Tuple{DataType, (Int64 for i=2:N)...}` more directly in the type definition?
2. If the type of `moduli` is going to be restricted by the constructor anyway should I eliminate the annotation in the type declaration?
3. Would I be better off using `0` as a sentinel value for `Int64` so my `Goose` can be `isbitstype`, but then having to replace `mod` with something that watches for this value?
``````modif(a,b) = b==0 ? a : mod(a,b)
``````

Do not be concerned that using
`modnz(a,b) = iszero(b) ? a : mod(a,b)` instead of `mod(a,b)`
would impact performance.
Do prefer working with an `isbitstype(type)` where performance matters and there is much computation is done.

You could do:

``````struct Goose{M}
remainders::Tuple{Int64,Vararg{Int64,M}}
moduli::Tuple{Type{Int64},Vararg{Int64,M}}
end
``````

but note that `M` is one less than your `N`.

`M` being smaller than `N` is probably a feature here, since this formulation conveniently forces me to rethink whether I ever need 0-Tuples, which, of course, I don’t.