pub struct TqlGb1<T, Out, F1: Fn(&T) -> Out, F2: Fn(Out, &T) -> Out> {
f1: F1,
f2: F2,
}
I know that this can be solved via
_t: PhantomData<T>,
_out: PhantomData<Out>
=====
My question is: is this PhantomData absolutely required? If so, why? I feel like T, Out
are already "used" in F1/F2.
1 Like
The possibly more straightforward alternative is to drop the Fn
bounds alltogether and only apply them to impl
blocks etc. (They would be needed on the impl
blocks (or on the individual methods) anyways.)
So
pub struct TqlGb1<F1, F2> {
f1: F1,
f2: F2,
}
impl<F1, F2> TqlGb1<F1, F2>
{
// your methods here …
fn some_method<T, Out>(&self)
where
F1: Fn(&T) -> Out,
F2: Fn(Out, &T) -> Out,
{
// …
}
}
Edit: Nevermind, it won’t work as a bound on the impl directly. But you can put it on all the methods (when it’s needed)… I fixed the code above ^^
6 Likes
The right way to go is @steffahn 's suggestion, but if you can't for some reason, for right covariance, use PhantomData
but with fn()
:
pub struct TqlGb1<T, Out, F1: Fn(&T) -> Out, F2: Fn(Out, &T) -> Out> {
f1: F1,
f2: F2,
_marker: PhantomData<(fn(&T) -> Out, fn(Out, &T) -> Out)>,
}
5 Likes
This probably isn't very useful, but with the unstable Fn
traits you can get rid of the Out
parameter:
#![feature(unboxed_closures)]
pub struct TqlGb1<T, F1, F2>
where
F1: for<'a> Fn<(&'a T,)>,
F2: for<'a> Fn<(<F1 as FnOnce<(&'a T,)>>::Output, &'a T), Output=<F1 as FnOnce<(&'a T,)>>::Output>
{
f1: F1,
f2: F2,
_t: PhantomData<fn(&T)>,
}
5 Likes
system
Closed
August 4, 2021, 9:47pm
6
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.