From 313ed45c6942846c138b495c4140c6e49f7189e5 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Thu, 22 May 2025 20:22:48 +0200 Subject: [PATCH] feat: heterogeneous-list with reverse! --- .gitignore | 1 + Cargo.lock | 7 +++++ Cargo.toml | 6 ++++ src/hlist.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 38 ++++++++++++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/hlist.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..bb8d44a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "heterogeneous-list" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..871faf9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "heterogeneous-list" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/src/hlist.rs b/src/hlist.rs new file mode 100644 index 0000000..1ea1b83 --- /dev/null +++ b/src/hlist.rs @@ -0,0 +1,83 @@ +use hidden::HList_; + +mod hidden { + pub trait HList_ {} +} + +pub trait Reversed +{ + type Output: HList_; + fn reversed_prepend(self, cont: Cont) -> Self::Output; +} + +impl Reversed for Nil + where Cont: HList_ +{ + type Output = Cont; + + fn reversed_prepend(self, cont: Cont) -> Self::Output { + cont + } +} + +impl Reversed for Cons + where + Cont: HList_, + Rest: HList_ + Reversed>, + Self: HList_, + Cons: HList_ +{ + type Output = >>::Output; + + fn reversed_prepend(self, cont: Cont) -> Self::Output { + self.1.reversed_prepend(Cons(self.0, cont)) + } + +} + +pub trait HList + where + Self: Sized + HList_ + Reversed { + fn prepend(self, value: T) -> Cons { + Cons(value, self) + } + + type Reversed; + fn reversed(self) -> Self::Reversed; +} +impl HList for Nil { + + type Reversed = Self::Output; + + fn reversed(self) -> Nil{ + Nil + } +} +impl HList for Cons + where + Rest: HList_, + Self: Reversed +{ + type Reversed = Self::Output; + fn reversed(self) -> Self::Output { + self.reversed_prepend(Nil) + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)] +pub struct Cons(pub Item, pub Rest); +impl HList_ for Cons + where Rest: HList_ {} +impl Cons { + pub fn uncons(self) -> (Item, Rest) { + (self.0, self.1) + } + + pub fn head(&self) -> &Item { + &self.0 + } +} + +#[derive(Debug, Default, Clone, Copy)] +pub struct Nil; +impl HList_ for Nil {} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..3282098 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,38 @@ +use crate::hlist::HList; +use hlist::Nil; + +pub mod hlist; + +fn main() { + let x = Nil +.prepend(0) +.prepend(1) +.prepend(2) +.prepend(3) +.prepend(4) +.prepend(5) +.prepend(6) +.prepend(7) +.prepend(8) +.prepend(9) +.prepend(10) +.prepend(11) +.prepend(12) +.prepend(13) +.prepend(14) +.prepend(15) +.prepend(16) +.prepend(17) +.prepend(18) +.prepend(19) +.prepend(20) +.prepend(21) +.prepend(22) +.prepend(23) +.prepend(24) +.prepend(25); + println!("{x:#?}"); + let y = x.reversed(); + println!("{y:#?}"); +} +