> this function signature must be EXACTLY like what I wrote or it won't work
This can be seen as a feature in the sense that you can't program by luck: well, this incantation seems about right and the compiler nods its head that it understands and that means something, so it must be right.
No, it's because the function you're returning is of type FnMut(&B) -> C, but your F function is of type FnMut(B) -> G. It expects an owned value of B, but you only have a borrowed reference to a B. Just make F of type FnMut(&B) -> G and you no longer have to dereference and no longer need the restriction that B: Copy. Higher-ranked lifetime values don't have anything to do with it.
Here's the new version:
fn apply<A, B, C, F, G>(mut f: F, a: A)
-> impl FnMut(&B) -> C
where F: FnMut(&B) -> G,
G: FnMut(A) -> C,
A: Clone {
move |b| f(b)(a.clone())
} error[E0281]: type mismatch: the type `fn(_) -> _ {tool::second::<_>}` implements the trait `std::ops::FnMut<(_,)>`, but the trait `for<'r> std::ops::FnMut<(&'r _,)>` is required (expected concrete lifetime, found bound lifetime parameter
--> src\lib.rs:50:17
|
50 | .filter(apply(second, i))
| ^^^^^
|
= note: required by `apply`
error[E0271]: type mismatch resolving `for<'r> <fn(_) -> _ {tool::second::<_>} as std::ops::FnOnce<(&'r _,)>>::Output == _`
--> src\lib.rs:50:17
|
50 | .filter(apply(second, i))
| ^^^^^ expected bound lifetime parameter , found concrete lifetime
|
= note: concrete lifetime that was found is lifetime '_#11r
= note: required by `apply`
error: aborting due to 2 previous errors
error: Could not compile `fizzbuzz`. fn main() {
for i in 1..101 {
if i % 15 == 0 {
println!("FizzBuzz");
} else if i % 3 == 0 {
println!("Fizz");
} else if i % 5 == 0 {
println!("Buzz");
} else {
println!("{}", i);
}
}
}https://bitbucket.org/iopq/fizzbuzz-in-rust/src/bf4968973d73...
I hope their production code isn't like this.
If you want production code look at Rust and Servo.
.unwrap_or_else(|| i.to_string().into())
this is the only one that was too ugly to make point-freehttps://github.com/the-guitarman/rust_fizzbuzz/blob/master/s...
template<class F, class A>
auto apply(F f, A a) {
return [f=std::move(f), a=std::move(a)](auto&& b) {
return f(std::forward<dectlype(b)>(b))(a);
}
}
The forward<decltype> is an abomination and is really in need of a language based solution, but otherwise is fairly straightforward.[1] No type checking of the definition of course, only of instantiations. On the plus side, the returned function is polymorphic and can be called for all Bs that f can be called.
https://bitbucket.org/iopq/fizzbuzz-in-rust/src/bf4968973d73...
it gives an error when I use a generic `second` method from tool.rs