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

- Is there a way to eliminate the
`Union`

and specify`Tuple{DataType, (Int64 for i=2:N)...}`

more directly in the type definition? - If the type of
`moduli`

is going to be restricted by the constructor anyway should I eliminate the annotation in the type declaration? - 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)
```