I'm tinkering with a for-fun port of Redux to Rust, to try to get a better handle on the way Rust handles generics and closures. I've run into a bit of a snag.
This works, but requires an additional temporary variable that I'd like to eliminate:
pub trait Reducer<S, A> {
fn reduce(&self, state: &S, action: &A) -> S;
}
impl<S, A, F: Fn(&S, &A) -> S> Reducer<S, A> for F {
fn reduce(&self, state: &S, action: &A) -> S {
self(state, action)
}
}
pub struct Store<'a, S, A> where
S: 'a,
A: 'a {
state: S,
reducer: &'a Reducer<S, A>,
}
impl<'a, S, A> Store<'a, S, A> {
pub fn from_state(initial_state: S, reducer: &'a Reducer<S, A>) -> Store<'a, S, A> {
// …
}
}
The offending temporary:
fn add(state: &i32, action: &i32) -> i32 {
state + action
}
let reducer = &add; // <-- cannot be inlined
let mut store = redux::Store::from_state(5, reducer);
This doesn't compile, and complains about A
:
// Reducer is unchanged.
pub struct Store<S, A, R: Reducer<S, A>> {
state: S,
reducer: R,
}
error[E0392]: parameter `A` is never used
--> src/store.rs:8:21
|
8 | pub struct Store<S, A, R: Reducer<S, A>> {
| ^ unused type parameter
Which is a pity, because I was hoping I could do this and eliminate the temporary.
fn add(state: &i32, action: &i32) -> i32 {
state + action
}
let mut store = redux::Store::from_state(5, add);
As far as I can see, the A
type parameter is actually used in the latter definition of Store
, but only in the definition of further type parameters. How would I satisfy the compiler, here?