Here's a quick attempt, at doing what you want in Rust. I have used something like the HList idea to define a type-list with append and fold, see: Rust Playground
This is the module defining the mechanism
mod hlist {
pub struct Nil;
pub struct Cons<H, T> {head : H, tail : T}
pub trait TypeList {type Head;}
impl TypeList for Nil {type Head = Nil;}
impl<H, T> TypeList for Cons<H, T> where T : TypeList {type Head = H;}
pub trait Append<A> : TypeList {
type Output;
fn append(self, x : A) -> Self::Output;
}
impl<A, T> Append<A> for T where T : TypeList {
type Output = Cons<A, Self>;
fn append(self, x : A) -> Self::Output {
Cons {head : x, tail : self}
}
}
pub trait With<T, A> {
fn with(&self, x : &T, y : A) -> A;
}
pub trait Fold<F, A> : TypeList {
fn fold(&self, f : &F, a : A) -> A;
}
impl<F, A> Fold<F, A> for Nil {
fn fold(&self, _ : &F, a : A) -> A {
a
}
}
impl<H, T, F, A> Fold<F, A> for Cons<H, T> where T : Fold<F, A>, F : With<H, A> {
fn fold(&self, f : &F, a : A) -> A {
f.with(&self.head, self.tail.fold(f, a))
}
}
}
After that this is all we need to define a collection and process it:
fn main() {
use hlist::{Nil, With, Append, Fold};
let collection = Nil.append("a").append(23i32);
struct Print;
impl<T> With<T, ()> for Print where for<'a> &'a T : std::fmt::Debug {
fn with(&self, x : &T, _ : ()) {
println!("{:?}", x);
}
}
collection.fold(&Print, ());
}
You can put any type in the collection, no bounds, and when you fold over the collection Debug (or whatever other trait requirements must be defined on all elements in the collection).