How do we compose with unknown type fields in traits?

I am trying to model my application sort of like transducer like framework. And I am kind of stuck on how I can dynamically compose them based on user input.

struct Compose<Left, Right, L, R, F> {
    left: Left,
    right: Right,
    fn: F,
    _l: std::marker::PhantomData<L>,
    _r: std::marker::PhantomData<R>,
}

trait TestPull<T> {
    type State;
    fn initial(&self) -> Self::State;
    fn next(&self, state: &Self::State) -> T;
}

fn compose<Left, Right, L, R, F>(left: Left, right: Right, func: F) -> Compose<Left, Right, L, R, F>
where
    Left: TestPull<L>,
    Right: TestPull<R>,
{
    Compose {
        left,
        right,
        func,
        _l: std::marker::PhantomData,
        _r: std::marker::PhantomData,
    }
}

impl<Left, Right, L, R> TestPull<(L, R)> for Compose<Left, Right, L, R>
where
    Left: TestPull<L>,
    Right: TestPull<R>,
{
    fn initial(&self) -> (Left::State, Right::State) {
        (self.left.initial(), self.right.initial())
    }

    fn next(&self, state: &(Left::State, Right::State)) -> (L, R) {
        (self.left.next(&state.0), self.right.next(&state.1))
    }
}

fn less<L, R>(left: dyn TestPull<L>, right: dyn TestPull<R>) {
    compose(left, right, |l, r| l < r)
}

The less fails with the Self::State should be specified error. I understand there is no way to get it working without that, I am kind of not getting any direction on how I can model this without the state field. I am losing my sleep over this :frowning:

Your code is so abstract that it is hard to see what changes might help you, versus those which would defeat the point. Can you give a couple examples of what implementations of TestPull do?

(I suspect, but am not certain, that you are trying to do something which cannot be done dynamically at all.)

1 Like

Since you're having trouble modeling this in Rust, it's also hard for me to understand what you're trying to model to provide advice. Perhaps it would help if you could describe how you want the system to work using a different language, such as Python, C, or English.

1 Like

It's easy to fix: Rust Playground [1]

impl<Left, Right, L, R> TestPull<(L, R)> for Compose<Left, Right, L, R>
...
{
+    type State = (Left::State, Right::State);

But I agree with others that you should describe your goal first.


  1. also add some minor fixes to make code compile ↩ī¸Ž

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.