How to state equivalence between typeclasses?

Hi
I have two traits that look somewhat like the following:

trait Runner {fn run(&self){}}
trait Hunter {fn hunt(&self){}}

Now I want to state that every hunter is a runner. For it I write:

impl Runner for Hunter {} //compiler warns that dyn is for some reason required

Then I write some code like this:

struct Dog {}
impl Hunter for Dog {}
Dog{}.run

And I expect any dog to know how to run because it knows how to hunt, as was explicitly stated. But for some reason, compiler freaks out and emits error saying no method named runfound for structDoge in the current scope.
Am I doing it wrong or is it not possible at all? Also, why compiler wants to put dyn when you state equivalence for type classes? Would existential dyn Hunter and universal Dog types be equal, such that run() member would inhabit both or only the former one?

You want this:

impl<T> Runner for T where T: Hunter {}

This means, “for every concrete type T that is a Hunter, implement the Runner trait for T.”

dyn Hunter is a trait object type. Dog and dyn Hunter are both types that implement the Hunter trait. However, they are distinct types, so implementing a trait for one of them does not implement it for the other.

In older versions of Rust, dyn Hunter was just spelled Hunter. That is, the trait and the type had the same name. This was confusing, so the dyn keyword was added. The old syntax is deprecated but hasn't been removed yet, which is why your original code compiled with a warning.

5 Likes

You can also write

trait Hunter: Runner {}

to declare that Hunter may only be implemented for a type that already implements Runner -- which formalizes "every hunter is a runner".

Whether this technique (making Hunter into an extension trait) or @mbrubeck's suggestion (writing a blanket impl for Runner) will work better for you depends on the details of your code. If you want to implement Runner using the methods on Hunter, use a blanket impl. If the behavior described by Runner needs to be implemented separately from the extra behavior described by Hunter, use an extension trait.

4 Likes