Structures and TypeVar

Hi, I want to create a structure like:

struct Lattice{D, L, D1}
    # number of sites per dimension
    L::NTuple{D, Int}
    ...
    sites::Array{Site{L}, D1}
end

where D is just the dimension of the lattice and D1 is D+1. Since D1 is related to D there should be a way of writing this structure without D1, right? Thanks for any help :smiley:

1 Like

The short answer is that there isn’t. The solution StaticArrays uses is to have extra type parameters, but to define a constructor that means users don’t have to use the extra ones.

2 Likes

See ComputedFieldTypes.jl for a simple solution to this also

1 Like

I have the same need…

mutable struct Foo{N}
    x::Array{Float64,N}
    s::NTuple{N+1,Int64}
    function Foo(arraysize,extradimsize=10)
        nD = length(arraysize)
        x  = rand((arraysize...,extradimsize)...)
        s  = (arraysize...,extradimsize)
    new{nD}(x,s)
    end
end

I am a bit hesitant to add a dependency for it, but on the other side it seems a bit “complex” to use metaprogramming for it… can you just confirm there isn’t a simple solution for it ?

There is actually a trivial solution for you (though it does not fully generalize) for adding constants (whereas the original question was about subtraction):

s::Tuple{Int,Vararg{Int,N}}

or, similarly for multiplication:

t::NTuple{N,NTuple{N,Int}} # total element count is N^2
1 Like

There is indeed no way to get rid of an extra parameter to the outer struct if you want to have some type parameter in an inner field that is based on some computation of the outer parameter, no matter how trivial the computation is.

1 Like