Skip to content

Instantly share code, notes, and snippets.

@SrTobi
Created July 15, 2019 09:00
Show Gist options
  • Save SrTobi/696578809c133ce67f7ff9da2b471075 to your computer and use it in GitHub Desktop.
Save SrTobi/696578809c133ce67f7ff9da2b471075 to your computer and use it in GitHub Desktop.
trait HList: Sized {
fn len(&self) -> u32;
fn push<T>(self, value: T) -> Cons<T, Self>;
}
struct Cons<Head, Tail> where Tail: HList {
pub head: Head,
pub tail: Tail
}
impl<Head, Tail> HList for Cons<Head, Tail>
where
Tail: HList {
fn len(&self) -> u32 {
self.tail.len() + 1
}
fn push<T>(self, value: T) -> Cons<T, Self> {
cons(value, self)
}
}
impl<Head, Tail> std::fmt::Display for Cons<Head, Tail>
where
Tail: HList + std::fmt::Display,
Head: std::fmt::Display {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} :: {}", self.head, self.tail)
}
}
fn cons<Head, Tail>(head: Head, tail: Tail) -> Cons<Head, Tail> where Tail: HList {
Cons { head, tail }
}
struct Nil {}
impl HList for Nil {
fn len(&self) -> u32 {
0
}
fn push<T>(self, value: T) -> Cons<T, Self> {
cons(value, self)
}
}
impl std::fmt::Display for Nil {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Nil")
}
}
fn nil() -> Nil {
Nil {}
}
fn test<T: HList + std::fmt::Display>(list: T) -> Cons<i32, T> {
println!("{}", list);
list.push(11)
}
trait Sumable {
fn number(&self) -> i32;
}
impl Sumable for Nil {
fn number(&self) -> i32 {
0
}
}
impl<T: Copy + Into<i32>, Tail: HList+ Sumable> Sumable for Cons<T, Tail> {
fn number(&self) -> i32 {
self.head.into() + self.tail.number()
}
}
fn sum<T: Sumable>(list: T) -> i32 {
list.number()
}
fn main() {
let a = cons(1, nil()).push(10);
let b = test(a);
println!("{}", b);
println!("{}", sum(b));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment