Dear all,
Below is an MWE of the code I’m writing.
I’m using the abstract supertype Pairer as a ‘tag’. Its two type parameters specify the ionic inputs and outputs to concrete subtypes.
Joiner and Extender make new concrete subtypes of Pairer out of old ones, in such a way that the ionic inputs are extended:
abstract type Ion end
struct Sodium <: Ion end
struct Potassium <: Ion end
struct Calcium <: Ion end
struct Proton <: Ion end
abstract type Pairer{Inputs,Outputs} end
## Inputs and Outputs are either Ions or tuples of Ions
somehow_merge(Inputs, NewInputs) = Tuple{Inputs,NewInputs}
abstract type Extender{ExtraInput} end
## ExtraInput is either Ion or tuple of Ions
struct Joiner{Input,ExtraInput,Output} <: Pairer{somehow_merge(Input, ExtraInput),Output}
s::Pairer{Input,Output}
e::Extender{ExtraInput}
end
struct HappyPairer <: Pairer{Sodium,Potassium} end
struct SadPairer <: Pairer{Tuple{Sodium,Proton,Calcium},Calcium} end
struct CalcExtender <: Extender{Calcium} end
show_inputs(p::Pairer{S,A}) where {S,A} = S
hap = HappyPairer()
sad = SadPairer()
c = CalcExtender()
j = Joiner(hap, c)
show_inputs(j)
j2 = Joiner(sad, c)
show_inputs(j2)
show_inputs(j)
gives: Tuple{Sodium, Calcium}
. Great.
show_inputs(j2)
gives Tuple{Tuple{Sodium, Proton, Calcium}, Calcium}
. Bad.
What I want is for it to be Tuple{Sodium, Proton, Calcium}
. In other words, flatten the nested tuple and take out unique elements.
But I haven’t been able to figure out a somehow_merge
that can do this for tuples.
Now I should be able to pick through t1.parameters
and t2.parameters
where t1 and t2 are tuples of types, and then concatenate them to make a new tuple with all the elements of t1 and t2.
However, if I try modifying somehow_merge
to do this, I get errors like
exception =
│ type TypeVar has no field parameters.
…except it clearly does!
What’s going wrong? Can anybody make a somehow_merge
that gives
show_inputs(j2)
Tuple{Sodium, Proton, Calcium}
Thank you so much!