Consider the function
fn f(v: &[usize]) -> impl Iterator<Item = usize> + '_ {
v.iter().cloned()
}
I want to write a generic function g which accepts any function with the same signature as f, and calls that function with various lifetimes. Is this possible?
My attempt 1: I naively wrote
fn g<F>(f: F)
where
F: for<'a> Fn(&'a [usize]) -> (impl Iterator<Item = usize> + 'a) {}
but I got
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
My attempt 2: I tried to give g another type parameter for the specific iterator type:
fn g<F, I>(f: F)
where
I: Iterator<Item = usize>,
F: for<'a> Fn(&'a [usize]) -> I {}
I think this would work if the iterator were 'static. But in this case I'd need I to be a higher kinded type with one lifetime parameter. Concretely, this g compiles but doesn't accept f.
My attempt 3: As above, but giving g a lifetime parameter to specialize f:
fn g<'a, F, I>(f: F)
where
I: Iterator<Item = usize> + 'a,
F: Fn(&'a [usize]) -> I {}
This compiles and accepts f, but the body of g can only use f with the specific lifetime 'a.