Hi !
This is a strongly simplified example. I used transforming_fun
and resulting_fun
to give a bit of a picture as to what I'm trying to do.
I believe the issue here lies at Item = &'a (T, &'a T)
, which can't work because this tuple has a shorter lifetime then &'a T
, I have no clue how to assign a separate lifetime to the tuple and to &T
.
I
doesn't need to be taken by reference, but as I understand HKTB, the lifetime has to be issued at the "root" type, binding a lifetime only to an associated type isn't allowed.
This is a general problem I encountered many times before: how to pass down transformed iterators that hold references through functions. I always found a solution, but this time, the requirement extended to having the same generic with no lifetime passed through, which requires HKTB and comes with limitations I have no experience working around.
use std::fmt::Debug;
pub fn fun1<T: Debug, I>(par1: T, par2: I)
where
for<'a> &'a I: IntoIterator<Item = &'a T>,
{
fun2(par1, par2.into_iter().map(|x| (transforming_fun(x), x)))
}
fn fun2<T: Debug, I>(par1: T, par2: I)
where
for<'a> &'a I: IntoIterator<Item = &'a (T, &'a T)>,
{
for (x, y) in par2.into_iter() {
resulting_fun(par1, x, y)
}
}
fn transforming_fun<'a, T>(par: &'a T) -> T {
unimplemented!()
}
fn resulting_fun<'a, T>(par1: T, par2: &'a T, par3: &'a T) {
unimplemented!()
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0271]: type mismatch resolving `for<'a> <&'a I as IntoIterator>::Item == &'a (_, &'a _)`
--> src/lib.rs:7:5
|
3 | pub fn fun1<T: Debug, I>(par1: T, par2: I)
| - this type parameter
...
7 | fun2(par1, par2.into_iter().map(|x| (transforming_fun(x), x)))
| ^^^^ expected tuple, found type parameter `T`
...
10 | fn fun2<T: Debug, I>(par1: T, par2: I)
| ---- required by a bound in this
11 | where
12 | for<'a> &'a I: IntoIterator<Item = &'a (T, &'a T)>,
| --------------------- required by this bound in `fun2`
|
= note: expected reference `&(_, &_)`
found reference `&T`
error[E0308]: mismatched types
--> src/lib.rs:7:16
|
3 | pub fn fun1<T: Debug, I>(par1: T, par2: I)
| - this type parameter
...
7 | fun2(par1, par2.into_iter().map(|x| (transforming_fun(x), x)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `Map`
|
= note: expected type parameter `I`
found struct `Map<<&I as IntoIterator>::IntoIter, [closure@src/lib.rs:7:37: 7:65]>`
Some errors have detailed explanations: E0271, E0308.
For more information about an error, try `rustc --explain E0271`.
error: could not compile `playground` due to 2 previous errors
Thanks!