4 ms·
That line can be simplified to: fn compose<T, F: Fn(T)->T>(f1: F, f2: F) -> F {
by lachlan-sneff 7y ago
That line can be simplified to:
fn compose<T, F: Fn(T)->T>(f1: F, f2: F) -> F {
- tomjakubowski 7y agoLambdas have unique types, and you can't use a generic parameter in a return type (which is impl Trait's raison d'etre), so I think it would have to be this: fn compose<T, F: Fn(T) -> T, G: Fn(T) -> T>(f: F, g: G) -> impl Fn(T) - > T or: fn compose<T, F, G>(f: F, g: G) -> impl Fn(T) -> T where F: Fn(T) -> T, G: Fn(T) -> T
- Diggsey 7y agoMaybe you just miscommunicated, but you absolutely can use generic parameters in a return type: https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.collect https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.ht... ... and `impl Trait` exists to be able to have return types which are difficult, verbose, or impossible to name.
- YatoRust 7y agoYes, I think he meant that it would be a bad idea to lock all of the type parameters to the same type, because all closures have different types. So you wouldn't be able to do something like this compose(|x| x, |x| x) because the closures have the same type.
- lmm 7y agoBecause the closures don't have the same type, if I'm following you correctly.
- mathw 7y agoBecause the parameters demand the same type (and for the return value), but the supplied parameters are not the same type because the only way to get that is to pass in exactly the same instance of the closure. It's a fun little thing, and a good example of why impl Trait in argument position is a really nice addition to Rust, even though based on what we were originally excited about (impl Trait in return position for returning Iterators and other such things), the argument position form didn't seem so important.
- Sean1708 7y agoIt's impossible to write a compose function with the declaration fn compose<T, F: Fn(T) -> T>(f1: F, f2: F) -> F As far as I'm aware the only way to write a function like that is fn compose<T, F: Fn(T) -> T>(f1: F, f2: F) -> F { f1 } and even then you can only call it like this let clos = |x| 2 * x; compose(clos, clos);
- aratakareigen 7y agoReturn position impl Trait also exists so that you can change the actual return type without making a breaking change.
- deleted 7y ago[deleted]