I've asked about this in the past, but since the help channels were archived I thought it would be wise to start a thread.
Currently, I have some related types that work with multivectors from geometric algebra:
# Used to store information about the Clifford algebra an `AbstractMultivector` belongs to
struct CliffordAlgebra{P,N,Z} end
dimension(::Type{CliffordAlgebra{P,N,Z}}) where {P,N,Z} = P+N+Z
abstract type AbstractMultivector{Cl<:CliffordAlgebra,T<:Number} end
# Contains all grades; L is the total length of the data, 2^(P+N+Z)
struct Multivector{Cl,T,L}
...
end
# Contains only the even grades; L = 2^(P+N+Z-1)
struct EvenMultivector{Cl,T,L}
...
end
# Contains a single grade, K, L = binomial(dimension(Cl),K)
struct KVector{Cl,K,T,L}
...
end
Now, I want to define a promotion rule so that when you add two KVectors of different grades, it can convert to an EvenMultivector if both grades are even and a Multivector otherwise. Basically this:
function Base.promote_rule(::Type{<:KVector{Cl,K1,T1}}, ::Type{<:KVector{Cl,K2,T2}}) where {Cl,K1,K2,T1,T2}
T = promote_type(T1,T2)
return iseven(K1) && iseven(K2) ? EvenMultivector{Cl,T,2^(dimension(Cl) - 1)} : Multivector{Cl,T,2^dimension(Cl)}
end
Is there a way to accomplish something like this while achieving type stability? I know that the easy solution is just to promote pairs of KVectors with different grades to a Multivector every time (which is how I currently have it), but I'm more so just curious if an optimization like this could be made.