Search code examples
genericsrusttraitsassociated-types

Is it possible to use self-referential associated types when using generics?


Example: given the following trait,

trait DirectedAcyclicGraph<V, E> where V: Add, E: Add

I would like for whenever a value of the type V to a value of the same type that another value of type V is returned. Whenever a value of type E is added to another value of the same type I want another E to be returned.

Naively, I thought that this might be in the right direction,

trait DirectedAcyclicGraph<V, E> where V: Add<Output = V>, E: Add<Output = E>

but that was just a shot in the dark.

The documentation for Add supplies the following example,

use std::ops::Add;

struct Foo;

impl Add for Foo {
    type Output = Foo;

    fn add(self, _rhs: Foo) -> Foo {
        println!("Adding!");
        self
    }
}

fn main() {
    Foo + Foo;
}

but I cannot understand how to provide an implementation for a generic type in the same way, if that is even possible.


Solution

  • This ended up being a case of a programming error. As @ChrisMorgan pointed out in his example, the expression Add<Output = V> does compile. The reason the compiler wailed was that in one location in the production source-code Output = V had not been consistently added.

    Regrettably I must have also made some error when compiling the condensed MWE.

    So, the take-away for posterity is that

    trait DirectedAcyclicGraph<V, E> where V: Add<Output = V>, E: Add<Output = E>
    

    works.