[Solved] Struct/trait/generic "puzzle"

#1
  1. This is a follow up to: Generic type of trait?

  2. The code I have so far:


pub struct Cat {}
pub struct Dog {}

pub trait CanAllolcateStuffT {
    fn return_coll<T>() -> SomeColl<Self, T> {
    }
}

impl CanAllocateStuffT for Cat {
    // ???
}

impl CanAllocateStuffT for Dog {
    // ???
}


pub struct SomeColl<A, T> {
    inner: ... // want this to be Vec<T> when A = Cat, and Set<T> when A = Dogb
}

  1. Is there anyway to make this work?
0 Likes

#2

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=662bef43a6b422f064f5883dfd318324

Here’s one way, you could remove the Default bound on AnimalCollection::Collection if you want to, but then you will have to remove the default impl of return_coll, and move it into the impl Animal ... { fn return_coll() -> ... }

1 Like

#3
pub trait AnimalCollection<T> {
    type Collection: Default;
}

impl<T> AnimalCollection<T> for Cat {
    type Collection = Vec<T>;
}

impl<T: Eq + std::hash::Hash> AnimalCollection<T> for Dog {
    type Collection = HashSet<T>;
}

is brilliant. Is there a name for this pattern? I’ve been staring at this problem on/off for the past few days, and did not think of “inverting” it like this.

0 Likes

#4

I don’t think there is as name, but it is a common workaround for not having GATs.

0 Likes

#5

I think the pattern was first applied to Rust in this blog post.

1 Like