#![feature(associated_type_defaults)] // A Collection trait and collection families. Based on // https://smallcultfollowing.com/babysteps/blog/2016/11/03/ // associated-type-constructors-part-2-family-traits/ // run-pass trait Collection { type Iter<'iter>: Iterator where T: 'iter, Self: 'iter; type Family: CollectionFamily; // Test associated type defaults with parameters type Sibling: Collection = <>::Family as CollectionFamily>::Member; fn empty() -> Self; fn add(&mut self, value: T); fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; } trait CollectionFamily { type Member: Collection; } struct VecFamily; impl CollectionFamily for VecFamily { type Member = Vec; } impl Collection for Vec { type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter; type Family = VecFamily; fn empty() -> Self { Vec::new() } fn add(&mut self, value: T) { self.push(value) } fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { self.iter() } } fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member where C: Collection, { let mut res = ::Member::::empty(); for &v in ints.iterate() { res.add(v as f32); } res } fn use_floatify() { let a = vec![1, 2, 3]; let b = floatify(&a); assert_eq!(Some(&1.0), b.iterate().next()); } fn main() { use_floatify(); }