[no description]
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..2b2f999 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,170 @@ +#![feature(tuple_trait, import_trait_associated_functions, never_type)] +#![no_std] +#![allow(mixed_script_confusables, confusable_idents)] +//!  +//! +//! start with [`Tupl`]. +mod implementations; +mod picks; +/// Reverse a tuple. +pub trait Reverse: Tupl { + type Reversed: Tupl; + fn reverse(self) -> Self::Reversed; +} +#[doc(inline)] +pub use Reverse::{reverse, reverse as flip}; +#[doc(inline)] +pub use Tupl::{drop, head, head as left, head as fst, last, last as right, pick, take}; +pub use picks::*; +/// Construct a tuple. +pub fn cons<T, Tup: Cons<T>>(x: T, y: Tup) -> Tup::Cons { + Tup::Cons::cons(x, y) +} +/// Construct a tuple, backwards. +pub fn snoc<T, Tup: Cons<T>>(x: Tup, y: T) -> Tup::Snoc { + Tup::Snoc::snoc(x, y) +} +/// alias for [`snoc`] +pub trait Push<T>: Tupl { + type Result; + /// ``` + /// use ttools::*; + /// let x = (1, 2).push(3); + /// assert_eq!(x, ((1, 2, 3))); + /// ``` + fn push(self, other: T) -> Self::Result; +} +/// alias for [`cons`] +pub trait With<T: Tupl> { + type Result; + /// ``` + /// use ttools::*; + /// let x = 1.with((2, 3)); + /// assert_eq!(x, ((1, 2, 3))); + /// ``` + fn with(self, other: T) -> Self::Result; +} + +// implemented for the constructed type +pub trait Cons<T>: Tupl { + /// (T, ..self) + type Cons: Tupl<Head = T, Tail = Self>; + /// (..self, T) + type Snoc: Tupl<Last = T, Init = Self>; +} +/// backing trait for [`take`]. +pub trait TD<const N: usize>: Tupl { + /// self[N..] + type Drop: Tupl; + /// self[..N] + type Take: Tupl; + // self[LEN - N..] + type TakeB: Tupl; + /// self[..LEN - N] + type DropB: Tupl; + /// deconstruct + fn dropf(self) -> (Self::Take, Self::Drop); + /// deconstruct + fn dropb(self) -> (Self::DropB, Self::TakeB); +} +/// backing trait for [`pick`] +pub trait Pick<const N: usize>: Tupl { + /// `self[N]` + type At; + /// self[..N] + type L: Tupl; + /// self[N + 1..] + type R: Tupl; + /// reconstruct + fn repick(l: Self::L, at: Self::At, r: Self::R) -> Self; + /// deconstruct + fn depict(self) -> (Self::L, Self::At, Self::R); +} +/// Main tuple trait. +pub trait Tupl: core::marker::Tuple { + /// Refer to listmonster. + type Head; + /// Refer to listmonster. + type Last; + /// Refer to listmonster. + type Tail: Tupl; + /// Refer to listmonster. + type Init: Tupl; + /// Middle section of listmonster. + type Inner: Tupl; + /// Size of tuple. + const LEN: usize; + /// Note: Partial function. + #[doc(alias = "left")] + fn head(self) -> Self::Head + where + Self: Sized, + { + self.uncons().0 + } + /// Note: Partial function. + #[doc(alias = "right")] + fn last(self) -> Self::Last + where + Self: Sized, + { + self.unsnoc().1 + } + + /// Note: Partial function. + fn take<const N: usize>(self) -> Self::Take + where + Self: TD<N> + Sized, + { + self.dropf().0 + } + /// Note: Partial function. + fn drop<const N: usize>(self) -> Self::Drop + where + Self: TD<N> + Sized, + { + self.dropf().1 + } + /// Note: Partial function. + fn take_back<const N: usize>(self) -> Self::TakeB + where + Self: TD<N> + Sized, + { + self.dropb().1 + } + /// Note: Partial function. + fn drop_back<const N: usize>(self) -> Self::DropB + where + Self: TD<N> + Sized, + { + self.dropb().0 + } + /// Gives you the element at index N (from 0). + /// Note: partial function + fn pick<const N: usize>(self) -> Self::At + where + Self: Pick<N> + Sized, + { + self.depict().1 + } + + /// unconstructs self, returning head and tail (see listmonster) + fn uncons(self) -> (Self::Head, Self::Tail); + /// untcurtsnocs self, returning init and last (see listmonster) + fn unsnoc(self) -> (Self::Init, Self::Last); + /// weird thing, full construct + fn fcons(start: Self::Head, inner: Self::Inner, last: Self::Last) -> Self; + /// reconstruct; dont use directly + fn cons(head: Self::Head, tail: Self::Tail) -> Self; + /// retcurtsnoc; dont use directly + fn snoc(init: Self::Init, last: Self::Last) -> Self; +} + +#[test] +fn t() { + 2.with(cons(4i8, (1i16, 2i32)).push(2)) + .take::<2>() + .push(4) + .push(0u8) + .pick::<3>(); +} |