I lack the vocabulary to appropriately express the question succinctly, so I apologize if the title question is confusing.
Suppose you can define a binary infix operator that produces tuples, and you want this operator to be able to simultaneously:
- Extend a tuple to arbitrary length by appending additional elements
- Support nested tuples (in that they are not "flattened" into the tuple)
Suppose the operator is represented by ., I can do (1.) in pseudocode by:
define generic <Type T (T != Tuple), Type U>
operator (.) (T left, U right) => Tuple<T, U> {
createTuple(left, right);
}
define generic <Type... T, Type U>
operator (.) (Tuple<...T> left, U right) => Tuple<...T, U> {
appendTuple(left, right);
}
This violates (2.) though, if the leftmost value is a tuple:
# Good
1 . 2 . 3 . 4 -> (1, 2) . 3 . 4 -> (1, 2, 3) . 4 -> (1, 2, 3, 4)
# Also good
1 . (2, 3) . 4 -> (1, (2, 3)) . 4 -> (1, (2, 3), 4)
# Bad
(1, 2) . 3 . 4 -> (1, 2, 3) . 4 -> (1, 2, 3, 4)
What I'd like is to get ((1, 2), 3, 4) for the last example. The only way I can think to do this would require constraining the types, which I would like to avoid. Is something like this even possible, in any programming language or type system?