Emm… Let me take a look at this claim.
The requirement of my match on Result<T,E> is trying to turn this enum into a flat tuple that preserve all information.
In theory, all enums can be turned into a tuple like this, as long as we have Option type. This the way Go goes, and obviously it have its own use although I believe Rust’s way is better.
So if we have Go program to port, making this enum-to-tuple conversion easy is a big benifit because it makes the translation of logic much easier.
Even without it, the ability to turn an enum into a tuple can still be benificial like the example given - The original Reddit post writer tried to return impl Trait from different match arms, but this does not work.
Instead of using Box<dyn Trait> or Either, this gives another elegant solution and I didn’t realised when I have the same issue multiple times when using tokio, until I successfully solved that puzzle with my new solution.
This idea can be make more general: as long as we have enough good functiosn for Option to make things easy without pattern match on it.
So yes, I believe this pattern would have been used offen enough to justify, as today many real world code suffer or lack of hintsight on the possible to use this.
fn operation1() -> impl Future<Item=(), Error=()>{
...
}
fn operation2() -> impl Future<Item=(), Error=()>{
...
}
//Not compiling!
//fn operation3(condition: bool) -> impl Future<Item=(), Error=()> {
// if b {
// operation1()
// } else {
// operation2()
// }
//}
//we only have to write this once! or we can put it in std
fn optional_future<T,I,E,Fu,F>(t: T, f: F) -> impl Future<Item=Option<I>, Error=E>
where Fu: Future<Item=I, Error=E>,
F: FnOnce(Option<T>) -> Fu
{
// Use Either maybe?
// Or impl<F,I,E> Future for Option<F> where F: Future<Item=I, Error=E>
}
fn operation3(condition: bool) -> impl Future<Item=(), Error=()> {
match (condition,()) {
(true,t?) | (false,f?) =>
optional_future(t, |_| operation1())
.join(optional_future(f, |_| operation2()))
.and_then(|_,_| {})
}
}