Well, I wouldn't say it's exactly the same sequencing in terms of FP languages like Scala et al., but it does the job for the given collection types in Rust; invert something of type F<G<A>> into G<F<A>> .

Usually, we'd expect F and G as types that are iterable and applicative. In the case of Rust, what I seem to understand from the standard library is that it is expected that there exists a trait implementation— FromIterator —that should allow G to be treated like an applicative. Since collect() is already iterating over a collection of G<A> , it's straightforward for an implementation of FromIterator for F to turn the results (i.e. a collection of them) of the first FromIterator into a G<F<A>> —which is what it does.



let opt = vec! [ Some ( 1 ), Some ( 2 ), Some ( 3 )]; let sequenced = opt .into_iter () .collect :: < Option < Vec < i32 >>> (); print! ( "{:?}" , sequenced ); // Some([1, 2, 3]) let opt = vec! [ Some ( 1 ), None , Some ( 3 )]; let sequenced = opt .into_iter () .collect :: < Option < Vec < i32 >>> (); print! ( "{:?}" , sequenced ); // None let result = vec! [ Ok ( 1 ), Ok ( 2 ), Ok ( 3 )]; let sequenced = result .into_iter () .collect :: < Result < Vec < i32 > , & str >> (); print! ( "{:?}" , sequenced ); // Ok([1, 2, 3]) let result = vec! [ Ok ( 1 ), Err ( "oops" ), Ok ( 3 )]; let sequenced = result .into_iter () .collect :: < Result < Vec < i32 > , & str >> (); print! ( "{:?}" , sequenced ); // Err("oops") let result = vec! [ Ok ( 1 ), Ok ( 2 ), Ok ( 3 )]; let sequenced = result .into_iter () .map (| opt_i | opt_i .map (| i | i + 1 )) .collect :: < Result < Vec < i32 > , & str >> (); print! ( "{:?}" , sequenced ); // Ok([2, 3, 4])

originally posted as a gist.