Overloading operator with Fn constrained types

Hello

This code just want to implement a basic time-function generator

type sound = f64;

struct Ugen<T>
    where T : Fn(f64) -> sound, 
{ 
    time: f64,
    handler: T
}
impl<T> Ugen<T>
    where T : Fn(f64) -> sound, 
{
    pub fn new(handler: T) -> Self { Ugen{time: 0.0, handler} }
}
impl<T> Iterator for Ugen<T>
    where T : Fn(f64) -> sound,
{
    type Item = sound;
    fn next(&mut self) -> Option<Self::Item> {
        self.time += 0.1;
        Some((self.handler)(self.time))
    }
}

That is the basic implementation. It just acts like a sinus generator if created like let i = Ugen::new(|time| -> sound { time.sin() });

Now, i would like to implement a + overloading, to simulate something like Sin(x) + Sin(y), I was thinking doing something like fn add(self, rhs:Ugen<U>) -> Self::Output { Ugen::new(|time| { self.next().unwrap() + rhs.next().unwrap()}) }

The problem is, if I understand correctly, I have to specify 3 differents traits, two for the inputs and one for the output, like the used closures are not exactly the same type (like variables bindings etc.)

I could not achieve this because I would need to bind a new generic trait in the output type of the Add trait, and it seems impossible :frowning:

Any help greatly wanted ! :slight_smile:

impl<T, U> std::ops::Add<Ugen<U>> for Ugen<T> where
    T : Fn(f64) -> sound,
    U : Fn(f64) -> sound,
{
    type Output = Ugen<UKN_TRAIT>; // here is the problem, since i can not declare it in the trait impl def

    fn add(self, rhs:Ugen<U>) -> Self::Output
    {
        Ugen::new(|time| { self.next().unwrap() + rhs.next().unwrap()})
    }
}

I would restructure your code a bit to not depend on Fn(..) -> .. directly by introducing a single trait and one more type for Add

playground

This way is more robust and extensible.


This sort of question is better asked on users.rust-lang.org before you try and change the language. This forum is for discussion of the Rust programming language and the Rust compiler(s)

3 Likes