No problem at all. For me it's a nice practice to browse through the forum and look for problems and figure out the solution. It helps to memorize language constructs better.
As an exercise, I tried to see if I can name the type explicitly. Note that the following is not idiomatic, and it likely comes with some runtime overhead because the closures (which are in fact functions because they don't capture any environment) must be cast to function pointers (see also: What is the exact type of a function?):
use std::iter::{Filter, Map};
use std::ops::Range;
fn evens_squared(n: usize) ->
Map<
Filter<
Range<usize>,
for<'a> fn(&'a usize) -> bool
>,
fn(usize) -> usize
>
{
(1..n).filter((|x| x % 2 == 0) as fn(&usize) -> _).map((|x| x * x) as fn(_) -> _)
}
fn main() {
for x in evens_squared(8) {
println!("{x}");
}
}
Type inference is a bit stubborn for the filter closure, I had to specify the argument type explicitly on the right side of "as
". In particular, it doesn't work to write (|x: &usize| x % 2 == 0) as fn(_) -> _
, as shown in the following:
- (1..n).filter((|x| x % 2 == 0) as fn(&usize) -> _).map((|x| x * x) as fn(_) -> _)
+ (1..n).filter((|x: &usize| x % 2 == 0) as fn(_) -> _).map((|x| x * x) as fn(_) -> _)
Errors:
Compiling playground v0.0.1 (/playground)
error[E0599]: the method `map` exists for struct `Filter<std::ops::Range<usize>, fn(&usize) -> bool>`, but its trait bounds were not satisfied
--> src/main.rs:13:59
|
13 | (1..n).filter((|x: &usize| x % 2 == 0) as fn(_) -> _).map((|x| x * x) as fn(_) -> _)
| ^^^ method cannot be called on `Filter<std::ops::Range<usize>, fn(&usize) -> bool>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`<fn(&usize) -> bool as FnOnce<(&usize,)>>::Output = bool`
which is required by `Filter<std::ops::Range<usize>, fn(&usize) -> bool>: Iterator`
`fn(&usize) -> bool: FnMut<(&usize,)>`
which is required by `Filter<std::ops::Range<usize>, fn(&usize) -> bool>: Iterator`
`Filter<std::ops::Range<usize>, fn(&usize) -> bool>: Iterator`
which is required by `&mut Filter<std::ops::Range<usize>, fn(&usize) -> bool>: Iterator`
For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` due to previous error
What's wrong here? I don't really understand the problem here.