Hi folks.
I have a problem that I'd like to be able to solve "well", but I'm open to the possibility that it isn't yet time. The rough idea is that I would like to abstract over the representation of some data that I have, and write an implementation that only requires the ability to access the data certain ways. I'm running in to pain points with references, and what seems like it might want HKT over lifetimes or something.
Imagine I had a &'a HashMap<K, Vec<(T, Vec<(V,i32)>)>>
. This lets me map keys K
into a thing that I can iterate over and get pairs &'a (T, Vec<(V,i32)>)
or more abstractly pairs (&'a T, X)
where X
is a thing I can iterate over and get pairs (&'a V, i32)
out of. The ability to produce things that iterate over references to T
s and V
s is the only feature I need from the type, and I would like to be able to use different concrete implementations; some use much less memory / are faster for specific settings; e.g. V = ()
, or "I know there is only one (T, Vec<(V,i32)>)
element".
This sound a bit complicated, but it is actually what I need. A simpler version is just: I would like to define a trait with an associated type that says "a reference to me is basically like a &'a Vec<T>
, in that it can be iterated over to get &'a T
references. I'd then be able to write a method that hands back references to this associated type, and other people would be able to iterate over its T
references.
I've read up a bit on IntoIterator
which seems great to implement for any &'a Vec<T>
replacement, and I'm comfortable doing that. Implementing it for &'a MyStorage<T>
or whatever makes lots of sense. What I'm less clear on is how (or whether) I can write the constraint for the associated type that a reference to it should implement IntoIterator
.
What I might like to write is
trait AbstractStorage<K, T> {
type Storage where &'a Storage : IntoIterator<Item = &'a T>;
fn lookup<'a,'b>(&'a self, key: &'b K) -> &'a Self::Storage;
}
The other option (which seems workable, but painful) is to not use associated types and expose the instance of the Storage
type to the methods that would otherwise be generic in implementors of AbstractStorage
. It seems a bit horrible, especially since I'll eventually need a second for the &'a Vec<(V,i32)>
replacement, but ... I'm also open to other suggestions! I like the references and would rather not have to clone the T
and V
s, though (they could be String
s or otherwise have owned memory).
Thanks for any tips. Will trade answers for high-throughput data-parallel frameworks.