Change:
Initial implementation in
A nice-to-have but not required would be someway for us to make this general so it can be used with other types, for example with . I saw mentioned in and the challenge is ergonomics.
Does it make sense to implement for ?
Then perhaps can also exist (maybe for consistency or for real use)? It's not an identity.
Nice addition The generalization of this, which we should experiment with when we get GATs, should just be  for any functor.
Conversions for and are just and, so, I'm not sure if they need dedicated functions.
I don't think so. The code below doesn't compile.
that's because you're missing
perhaps are we talking about different functions? My understanding is that is an involution. isn't, as it transforms both and into .
Also, is it just me, or does seem like a rather obscure expression? I feel like a Rust programmer coming across this who hasn't seen it before would be pretty confused.
Hi everyone, is there anything which prevents this useful feature from being stabilized? I've come here from a link from the docs about the feature, but I can't really find any ongoing argument here. Could it be that there's another issue with discussions towards stabilization of the feature? Thanks :)
Ping this has been sitting around for a year now and I don't expect we'll see much more experimentation with it if folks have to rely on a nightly feature. What would y'all think about stabilizing?
Sounds ok to me. fcp merge This issue tracks these methods: rust impl<T, EOption<Result<T, E{ pub fn transpose(self) -Result<Option<T, E{…} } impl<T, EResult<Option<T, E{ pub fn transpose(self) -Option<Result<T, E{…} }
Team member has proposed to merge this. The next step is review by the rest of the tagged teams: [ ] [x] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
This will be an improvement under any name, but here's an argument for stabilizing this as : Unlike and , doesn't have common meanings in mathematics and matrix algebra (including with SIMD) which would lead to confusion in such code. is a more common English word than . It feels less like jargon. is 5 characters shorter without compromising clarity, and most inherent methods on Option, Result, and Iterator have short names. The first point feels particularly compelling. This method will be used in all kinds of code. People reviewing code dealing with matrices will strongly expect to have a particular meaning that this use would violate.
The term to me feels like you're converting to , rather than swapping the order of a and . Same with .
Perhaps going with and might be better? To me, going from to is lifting the out, and the reverse is lifting the out. It feels way less like jargon while not being too verbose.
Agreed those would be better than . However, is usually associated with monadic operations, and you have to squint a bit to see it here. (Incidentally, Haskell calls this particular operation .) The semantic argument for is that we want this operation to "flip the type inside-out." However, I see where you're coming from in terms of reading this closer to "flipping a bit." Perhaps we should consider the merits of . While it's not a common word, it is an and a short word. It has precisely the correct meaning, "to turn inside out." It's not a word we'd ever be tempted to use for another purpose. We wouldn't have to include the name of the resulting type in the method name. And it doesn't come with the kind of associations with other behavior that words like , , and have. This wouldn't be the first time that technology rescued an old word from obscurity and gave it new life.
:bell: This is now entering its final comment period, as per the . :bell:
As someone who's already well aware of these two functions, I would not mind the name one bit. However, it has one disadvantage that should be considered: people will likely have a hard time searching for functions named in the . If they proceed to implement them themselves and only later find out about them, I'm very sure they will blame it on the functions' obscure name. Maybe it might be better to pick a slightly ambiguous name like or just for the sake of discoverability. Because these functions are only defined on two very narrowly defined types ( and ), I think a mix-up with functions defined e.g. on matrices seems unlikely to me.
RE My main concern is discoverability. Once you get past the "how will people think to see if this exists" (maybe a help in a compiler error?), there is the "how will it stand out". Personally, I gloss over weird names in libraries (e.g. in C++) and I think would fall in that category. No idea if this is because I assume they are for esoteric advanced stuff, an inherent blindspot of ignorance, or something else. I assume other people, especially new users, would do the same.
For discoverability, could the documentation for the and modules, and maybe even the Book, have sections on or examples of the use of ?
Regarding discoverability, it seems unlikely that anyone will first find these methods by name regardless of what we call them. There's just not a common name for this operation. People will find these 1) by searching the web for "convert Rust Result Option to Option Result" or "chain Rust Result methods with Option" or other variations, 2) by scanning the Option or Result documentation for a method of the correct signature, or 3) by being introduced to the concept through the book, through blogs, or through seeing discussions such as this one. Regarding matrices, as soon as you have a function that returns and you use the type for error handling, there's every likelihood of having code that will intermix with the matrix , , etc. operations.
The final comment period, with a disposition to merge, as per the , is now complete.
Someone proposed to have something close to for search this kind of feature.

Discussion:
/// assert_eq!(x, y.transpose()); /// ``` #[inline] <del> #[unstable(feature = "transpose_result", issue = "47338")] </del> <ins> #[stable(feature = "transpose_result", since = "1.33.0")] </ins> pub fn transpose(self) -> Result<Option<T>, E> { match self { Some(Ok(x)) => Ok(Some(x)),

/// # Examples /// /// ``` <del> /// #![feature(transpose_result)] /// </del> /// #[derive(Debug, Eq, PartialEq)] /// struct SomeErr; ///

/// assert_eq!(x.transpose(), y); /// ``` #[inline] <del> #[unstable(feature = "transpose_result", issue = "47338")] </del> <ins> #[stable(feature = "transpose_result", since = "1.33.0")] </ins> pub fn transpose(self) -> Option<Result<T, E>> { match self { Ok(Some(x)) => Some(Ok(x)),

#![feature(test)] #![feature(in_band_lifetimes)] #![feature(crate_visibility_modifier)] <del> #![feature(transpose_result)] </del> #![recursion_limit="512"]

<del> #![feature(transpose_result)] </del> #[derive(Copy, Clone, Debug, PartialEq)] struct BadNumErr;