I’m not a data structures person, so the right answer here might be “you’re doing it wrong, try this instead”; but I’ll start with the immediate question I have:
in a recursive type, is it not possible to have the type parameters of the fields be related to the type parameters of the struct itself? for example, if one were to try to define:
struct Simplex{T<:Any, dim, size}
x::Union{NTuple{size, Simplex{T, dim-1}}, T}
end
you get no method matching -(::Typevar, ::Int64).
what I'm actually trying to do
I have data which is ‘shaped’ like a n-dimensional regular simplex, by which I mean I often want the data which is along some specific edge, face, volume, hyper-volume, etc of the simplex. eg, say the data is 1:10 and the dimension is 2 (so size is 4), I would want to represent it like
(
(1),
(2, 3),
(4, 5, 6),
(7, 8, 9, 10)
)
since I’ll be needing last() (7, 8, 9, 10), last.() (1, 3, 6, 10), and first.() (1, 2, 4, 7) a lot.
or with the same data if the dimension (and size) was 3, I would want it to look like
(
((1)),
((2), (3, 4)),
((5), (6, 7), (8, 9, 10))
)
and the pieces I’d need are last() ((5), (6,7), (8,9,10)), last.() ((1), (3,4), (8,9,10)), last..() ((1), (2,4), (5,7,10)), and first..() ((1), (2,3), (5,6,8)). (if you’re really good at visualizing this kind of thing, you’ll notice those are the four faces on this 3d triangular pyramid)
most of them are 4- or 5- d, where faking it with an array starts getting really confusing; but they can be arbitrarily big (seen up to 10-d so far)
I tried defining it as
b(size, dim) = prod(size:dim+size-1)/prod(1:dim)
struct Simplex{T<:Any, dim, size}
x::Union{NTuple{size, Simplex{T, dimMinusOne}}, T} where dimMinusOne
Simplex{T, dim, size}(x::Vector{T}) where {T} = dim==1 ?
new{T, 1, size}(ntuple(n->Simplex{T}(x[n]), size)) :
new{T, dim, size}(ntuple(n->Simplex{T, dim-1, n}(x[b(n-1,dim)+1:b(n,dim)]), size))
Simplex{T}(x::T) where T = new{T, 0, 1}(x)
end
but Simplex{Int, 2, 2}([1, 2, 3]) says there’s no method.