I want to implement add trait for a struct which imlpements Fn trait

impl<A> Add for PathFunctionStruct<A> where A:PathFunction{
    type Output=PathFunctionStruct<A>;
    fn add(self,other:Self)->Self::Output{
        PathFunctionStruct(|t:Time| {self.0(t)+other.0(t)})
    }
}
pub struct PathFunctionStruct<A>(A) where A:PathFunction;
pub trait PathFunction: Fn(Time) -> Position + Sized {}
impl<T: Fn(Time) -> Position> PathFunction for T {}
pub struct Time(f64);
pub struct Position(f64, f64, f64);
impl Add for Position {
    type Output = Self;
    fn add(self, other: Self) -> Self::Output {
        Position(self.0 + other.0,self.1 + other.1,self.2 + other.2)
    }
}

I am trying to do Structure and Interpretation of Classical Mechanics in rust.
I want to be able to add path functions for particles just by using + sign instead of using add method. Is there a way to do this?
Well a way except using dyn keyword.

Since all closures are technically of different type Add is not working for PathFunctionStruct

Instead of trying to get this work with closures, just define a method on your own trait:

pub trait PathFunction {
    fn position_at(time: Time) -> Position;
}

then create concrete types for each desired operation (e.g. Add<F, G>), then implement PathFunction for them. Playground.

Other comments:

  • don't put bounds on struct definitions, it's unnecessary
  • don't call structs XYZStruct. It doesn't matter w.r.t. naming whether a type is a struct or an enum; that's an implementation detail. Name types after their semantics, not their mechanics.
2 Likes

Thanks. My method of using simple add function not even the add trait would have also failed because manually implementing Fn traits is not allowed.

Actually, if you don't need the Add trait, then the solution is much easier as you can just stick to returning closures and specify the return type as impl FnMut(Time) -> Position (or impl PathFunction). Playground.

That is what I am currently doing in my code.

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.