bendn 6 months ago
parent 9f87b48 · commit c53f490
-rw-r--r--src/lib.rs48
-rw-r--r--src/res.rs153
2 files changed, 191 insertions, 10 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 263e455..bac41a1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,26 +3,31 @@
use core::ops::FnMut;
use std::marker::Tuple;
-trait Head: Tuple {
+trait Head: Tuple + Last {
type Head;
type Tail: Tuple;
- fn rejoin(_: Self::Head, _: Self::Tail) -> Self;
+ fn ht(_: Self::Head, _: Self::Tail) -> Self;
}
-macro_rules! impls {(
+trait Last: Tuple {
+ type Init: Tuple;
+ type Last;
+ fn il(_: Self::Init, _: Self::Last) -> Self;
+}
+
+macro_rules! h {(
$($Hd:tt $($Tail:tt)*)?
-) => ($(impls!($($Tail)*);)?$(
+) => ($(h!($($Tail)*);)?$(
impl<$Hd $(, $Tail)*> Head for ($Hd, $($Tail),*) {
type Head = $Hd;
type Tail = ($($Tail, )*);
- fn rejoin($Hd: Self::Head, tail: Self::Tail) -> Self {
- let ($($Tail, )*) = tail;
+ fn ht($Hd: Self::Head, ($($Tail, )*): Self::Tail) -> Self {
($Hd, $($Tail),*)
}
})?)}
-impls![_13 _12 _11 _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 _0];
-
+h![_13 _12 _11 _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 _0];
+include!("res.rs");
impl<Args: Head, F: FnMut<Args> + Sized> Bind<Args> for F {}
pub trait Bind<Args: Head>: FnMut<Args> + Sized {
fn bind<T: Clone>(self, with: T) -> impl FnMut<Args::Tail, Output = Self::Output>
@@ -37,13 +42,36 @@ pub trait Bind<Args: Head>: FnMut<Args> + Sized {
impl<Args: Head, F: FnMut<Args>> FnOnce<Args::Tail> for Fn<Args, F> {
type Output = F::Output;
extern "rust-call" fn call_once(mut self, args: Args::Tail) -> Self::Output {
- let args = Args::rejoin(self.t, args);
+ let args = Args::ht(self.t, args);
self.f.call_mut(args)
}
}
impl<Args: Head<Head: Clone>, F: FnMut<Args>> FnMut<Args::Tail> for Fn<Args, F> {
extern "rust-call" fn call_mut(&mut self, args: Args::Tail) -> Self::Output {
- let args = Args::rejoin(self.t.clone(), args);
+ let args = Args::ht(self.t.clone(), args);
+ self.f.call_mut(args)
+ }
+ }
+ }
+ fn rbind<T: Clone>(self, with: T) -> impl FnMut<Args::Init, Output = Self::Output>
+ where
+ Args: Last<Last = T>,
+ {
+ return Fn { f: self, t: with };
+ struct Fn<Args: Last, F: FnMut<Args>> {
+ f: F,
+ t: Args::Last,
+ }
+ impl<Args: Last, F: FnMut<Args>> FnOnce<Args::Init> for Fn<Args, F> {
+ type Output = F::Output;
+ extern "rust-call" fn call_once(mut self, args: Args::Init) -> Self::Output {
+ let args = Args::il(args, self.t);
+ self.f.call_mut(args)
+ }
+ }
+ impl<Args: Last<Last: Clone>, F: FnMut<Args>> FnMut<Args::Init> for Fn<Args, F> {
+ extern "rust-call" fn call_mut(&mut self, args: Args::Init) -> Self::Output {
+ let args = Args::il(args, self.t.clone());
self.f.call_mut(args)
}
}
diff --git a/src/res.rs b/src/res.rs
new file mode 100644
index 0000000..0032149
--- /dev/null
+++ b/src/res.rs
@@ -0,0 +1,153 @@
+/*
+tup = lambda n: " ".join([f"_{n}," for n in range(n + 1)])
+for n in range(14):
+ print(f"""
+impl<{tup(n)}> Last for ({tup(n)}) {{
+ type Init = ({tup(n - 1)});
+ type Last = _{n};
+ fn il(({tup(n - 1)}): Self::Init, last: Self::Last) -> ({tup(n)}) {{
+ ({tup(n - 1)} last,)
+ }}
+}}
+""")
+*/
+impl<_0> Last for (_0,) {
+ type Init = ();
+ type Last = _0;
+ fn il((): Self::Init, last: Self::Last) -> (_0,) {
+ (last,)
+ }
+}
+
+impl<_0, _1> Last for (_0, _1) {
+ type Init = (_0,);
+ type Last = _1;
+ fn il((_0,): Self::Init, last: Self::Last) -> (_0, _1) {
+ (_0, last)
+ }
+}
+
+impl<_0, _1, _2> Last for (_0, _1, _2) {
+ type Init = (_0, _1);
+ type Last = _2;
+ fn il((_0, _1): Self::Init, last: Self::Last) -> (_0, _1, _2) {
+ (_0, _1, last)
+ }
+}
+
+impl<_0, _1, _2, _3> Last for (_0, _1, _2, _3) {
+ type Init = (_0, _1, _2);
+ type Last = _3;
+ fn il((_0, _1, _2): Self::Init, last: Self::Last) -> (_0, _1, _2, _3) {
+ (_0, _1, _2, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4> Last for (_0, _1, _2, _3, _4) {
+ type Init = (_0, _1, _2, _3);
+ type Last = _4;
+ fn il((_0, _1, _2, _3): Self::Init, last: Self::Last) -> (_0, _1, _2, _3, _4) {
+ (_0, _1, _2, _3, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5> Last for (_0, _1, _2, _3, _4, _5) {
+ type Init = (_0, _1, _2, _3, _4);
+ type Last = _5;
+ fn il((_0, _1, _2, _3, _4): Self::Init, last: Self::Last) -> (_0, _1, _2, _3, _4, _5) {
+ (_0, _1, _2, _3, _4, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6> Last for (_0, _1, _2, _3, _4, _5, _6) {
+ type Init = (_0, _1, _2, _3, _4, _5);
+ type Last = _6;
+ fn il((_0, _1, _2, _3, _4, _5): Self::Init, last: Self::Last) -> (_0, _1, _2, _3, _4, _5, _6) {
+ (_0, _1, _2, _3, _4, _5, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7> Last for (_0, _1, _2, _3, _4, _5, _6, _7) {
+ type Init = (_0, _1, _2, _3, _4, _5, _6);
+ type Last = _7;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7) {
+ (_0, _1, _2, _3, _4, _5, _6, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7, _8> Last for (_0, _1, _2, _3, _4, _5, _6, _7, _8) {
+ type Init = (_0, _1, _2, _3, _4, _5, _6, _7);
+ type Last = _8;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6, _7): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7, _8) {
+ (_0, _1, _2, _3, _4, _5, _6, _7, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7, _8, _9> Last for (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) {
+ type Init = (_0, _1, _2, _3, _4, _5, _6, _7, _8);
+ type Last = _9;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) {
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10> Last
+ for (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
+{
+ type Init = (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9);
+ type Last = _10;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) {
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11> Last
+ for (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)
+{
+ type Init = (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10);
+ type Last = _11;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) {
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12> Last
+ for (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12)
+{
+ type Init = (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11);
+ type Last = _12;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) {
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, last)
+ }
+}
+
+impl<_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13> Last
+ for (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13)
+{
+ type Init = (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12);
+ type Last = _13;
+ fn il(
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12): Self::Init,
+ last: Self::Last,
+ ) -> (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) {
+ (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, last)
+ }
+}