Do we need associated traits for GATs?

Consider a trait like:

trait Container<T> {
  type ContainerFamily<A>;
  fn map<A>(&self, mapper: &dyn Fn(&T) -> A) -> Self::ContainerFamily<A>;
}

It's ok to impl it for a struct like

struct Box<T> {
  val: T
}

impl<T> Container<T> for Box<T> {
  type ContainerFamily<A> = Box<A>;
  fn map<A>(&self, mapper: &dyn Fn(&T) -> A) -> <Self as Container<T>>::ContainerFamily<A> {
    return Box{val: mapper(&self.val)}
  } 
}

However it's not possible to impl on another struct with restrictions on type parameter T

struct Box2<T: Copy> {
  val: T
}

impl<T:  Copy> Container<T> for Box2<T> {
  type ContainerFamily<A> = Box2<A>; 
  //                       ^^^^^^^^ the trait bound `A: Copy` is not satisfied
  fn map<A>(&self, mapper: &dyn Fn(&T) -> A) -> <Self as Container<T>>::ContainerFamily<A> {
  //                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `A: Copy` is not satisfied
    return Box2{val: mapper(&self.val)}
  } 
}

If add where clause, make it to Box2::ContainerFamily<A: Copy>, it will have stricter requirements than trait, add compilier forbids that for now.
It seems the only solution for now is create specilized trait manually like:

trait CopyableContainer<T: Copy> {
  type ContainerFamily<A: Copy>;
  fn map<A: Copy>(&self, mapper: &dyn Fn(&T) -> A) -> Self::ContainerFamily<A>;
}

But with accociated traits we may be able to rewrite Container and impl it for Box2<T: Copy>:

trait Container<T> {
  trait Restriction;
  type ContainerFamily<A: Self::Restrinction>;
  fn map<A: Self::Restrinction>(&self, mapper: &dyn Fn(&T) -> A) -> Self::ContainerFamily<A>;
}

struct Box2<T: Copy + AsRef<String>> {
  val: T
}

impl<T:  Copy + AsRef<String>> Container<T> for Box2<T> {
  trait Restriction = Copy + AsRef<String>;
  type ContainerFamily<A: Self::Restriction> = Box2<A>; 
  fn map<A: Self::Restriction>(&self, mapper: &dyn Fn(&T) -> A) -> <Self as Container<T>>::ContainerFamily<A> {
    return Box2{val: mapper(&self.val)}
  } 
}

Infact trait Container<T, Restriction = Copy> is same with trait CopyableContainer, but the former has better code reusage and shared abstraction.
Is there any other approach for now to impl Container for Box2<T: Copy> in current nightly Rust?

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.