Shuffling tuples

I've been trying to come up with a means to, at compile time, arbitrarily shuffle tuples.

The idea would be to have an API something like:

assert_eq!((47u8, "cake", 123u32).shuffle::<(u32, u8)>(), (123u32, 47u8));

So you can reorder and/or drop elements based on how their types match between the input and output tuples.

I haven't managed to come up with anything that works and approaches this API.

Do you think it's possible, and if so, could you provide an implementation pointer?

Thanks in advance for any help.

I don't think this is possible in its full generality. What do you do with tuples of identical field types? How do you deal with generics, where the concrete types are not known, and as such, they may be identical or distinct? I see that this has all the problems "union types" (that also come up periodically) have, for similar reasons.

I had suspected as much, I think generally it's possible to define rules to resolve the ambiguities you describe but it doesn't seem like expressing the concept is possible in the language as is.

To constrain the problem, and possibly make it tractable; what if I only wanted to retain all the elements of some specified types in a tuple? Something like:

assert_eq!((0u8, "cake", 47u32).retain::<(u8, u32)>(), (0u8, 47u32));

It’s technically possible if you restrict the valid field types to a known subset and pull some really complicated trait shenanigans, but those have a tendency to bring the compiler to its knees for anything nontrivial. For any real application, you’ll be better off writing all of the necessary trait implementations explicitly (via macro). Or even better, accept the tiny amount of runtime cost to deal with a dyn- or enum-based solution.

1 Like