Function composition in the standard library

Abstract return types on its own wouldn’t completely replace this, or not as nicely, at least not without additional nontrivial extensions. You would have to write something like:

fn compose<A, B, C, F: Fn(A) -> B, G: Fn(B) -> C>(f: F, g: G) -> abstract Fn(A) -> C { move |a| g(f(a)) }

fn compose_mut<A, B, C, F: FnMut(A) -> B, G: FnMut(B) -> C>(f: F, g: G) -> abstract FnMut(A) -> C { move |a| g(f(a)) }

fn compose_once<A, B, C, F: FnOnce(A) -> B, G: FnOnce(B) -> C>(f: F, g: G) -> abstract FnOnce(A) -> C { move |a| g(f(a)) }

The issue is that there’s no way to say things like “the output abstract type is FnMut iff the input types are”. Off the top of my head, I don’t think the more-general formulation of named module-level abstract types would provide for this either. (And, for what it’s worth, my sense is that any extension enabling this would likely be too complex to be worthwhile, considering that you can just use structs with explicit impls for this instead.)

So I think that struct Compose is in fact the right way to do this, and will be for some time. Inclusion in std might be reasonable from my perspective.