[no description]
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs170
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)]
+//! ![view](https://raw.githubusercontent.com/learnyouahaskell/learnyouahaskell.github.io/e4282695721ed62b746d213aa81265f8c254fbf2/static/assets/images/starting-out/listmonster.png)
+//!
+//! 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>();
+}