Their naming is not symmetrical; you don’t have map_ok .
If you pick a topology where no two points are connected, then you’re not going to find much value in classifying things based on topology. Surely naming conventions are not a relevant notion of computational symmetry?
There is no iter_err() to correspond to .iter() (same for iter_mut ).
This may as well be a bug. There’s nothing about Result that makes this an invalid operation. It is only adherence to convention that prevents it from existing. (More importantly, the existance of this function would only be a concession to the symmetry between Result<T, E> and Result<E, T>; the symmetry is fundamental, so you can already recover the behavior of iter_err() by applying the isomorphism and calling .iter() on the result.)
also: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#impl-Product<Result<U%2C%20E>> has no corresponding impl for E .
This impl exists:
impl<E, U, T> Product<Result<U, T>> for Result<T, E> where E: Product<U>. Again, whether you use this impl or that one is a matter of convention.
You can’t pretend away ? ; the way it behaves for Result<T, E> blesses Ok and not Err as the happy path.
The ? operator blesses Ok as the easy-to-write path. Whether or not it is the ‘good’ or ‘happy’ path is context dependent.
I think it is quite clear that Result<T, E> is imbued with semantic meaning in the operations it has. It is not just a dumb coproduct, it is about reified exceptions
It is given a syntactic meaning… Semantically, it reifies a branch, and the code it generates makes no distinction between which branch is preferred over the other. (“exception” is too ill-defined to be encoded in the semantics of Result.)
Everything about Result that pushes you to prefer Ok over Err is artificial in the sense that is based in human expectations and conventions. The actual software that is produced doesn’t change, and thus the logic that generates it is the same in either case.