Open nwtgck opened 3 years ago
If you read the page you linked (https://doc.rust-lang.org/error-index.html#E0666), you need to define the type as a named generic parameter:
fn f1<F: FnMut(u32) -> u32, T: impl Iterator<Item=u32>>(a: u32) -> impl FnOnce(F) -> T {
move |f: F| {
(0..a).map(f)
}
}
fn main() {
let iter = f1(10)(|b| b * 2);
for x in iter {
println!("{:}", x);
}
}
@toothbrush7777777 Actually, I did. I think you mean the following, not T: impl Iterator...
fn f1_with_named_generic<F: FnMut(u32) -> u32, T: Iterator<Item=u32>>(a: u32) -> impl FnOnce(F) -> T {
move |f: F| {
(0..a).map(f)
}
}
Then, we will have a compile error as follows. So, I don't think a named generic parameter works...
error[E0308]: mismatched types
--> src/main.rs:31:9
|
29 | fn f1_with_named_generic<F: FnMut(u32) -> u32, T: Iterator<Item=u32>>(a: u32) -> impl FnOnce(F) -> T {
| - this type parameter
30 | move |f: F| {
31 | (0..a).map(f)
| ^^^^^^^^^^^^^ expected type parameter `T`, found struct `std::iter::Map`
|
= note: expected type parameter `T`
found struct `std::iter::Map<std::ops::Range<u32>, F>`
Here is another work around with type_alias_impl_trait
in Nightly Rust.
#![feature(type_alias_impl_trait)]
type IterU32<T> = impl Iterator<Item=u32>;
fn f1_with_impl_trait_alias<F: FnMut(u32) -> u32>(a: u32) -> impl FnOnce(F) -> IterU32<F> {
move |f: F| {
(0..a).map(f)
}
}
fn main() {
let iter = f1_with_impl_trait_alias(10)(|b| b * 2);
for x in iter {
println!("{:}", x);
}
}
Hi!
It will be nice to use impl Trait with higher-order functions like the following. But it occurs a compile error at
impl Iterator<Item=u32>
.Nested impl Trait: https://doc.rust-lang.org/error-index.html#E0666
expected behavior/work around
Here is an expected behavior and a work around. We need to write the type explicitly like
std::iter::Map<std::ops::Range<u32>, F>
instead ofimpl Iterator<Item=u32>
.[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20f1_with_explicit_type%3CF%3A%20FnMut(u32)%20-%3E%20u32%3E(a%3A%20u32)%20-%3E%20impl%20FnOnce(F)%20-%3E%20std%3A%3Aiter%3A%3AMap%3Cstd%3A%3Aops%3A%3ARange%3Cu32%3E%2C%20F%3E%20%7B%0A%20%20%20%20move%20%7Cf%3A%20F%7C%20%7B%0A%20%20%20%20%20%20%20%20(0..a).map(f)%0A%20%20%20%20%7D%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20let%20iter%20%3D%20f1_with_explicit_type(10)(%7Cb%7C%20b%20*%202)%3B%0A%20%20%20%20for%20x%20in%20iter%20%7B%0A%20%20%20%20%20%20%20%20println!(%22%7B%3A%7D%22%2C%20x)%3B%0A%20%20%20%20%7D%0A%7D%0A)
The output should be the following.
It will be harder to write and read the return type when we append other methods after the
.map(f)
.