#![feature(tuple_trait, unboxed_closures, fn_traits)] #![allow(private_bounds)] use core::ops::FnMut; use std::marker::Tuple; trait Head: Tuple + Last { type Head; type Tail: Tuple; fn ht(_: Self::Head, _: Self::Tail) -> Self; } trait Last: Tuple { type Init: Tuple; type Last; fn il(_: Self::Init, _: Self::Last) -> Self; } macro_rules! h {( $($Hd:tt $($Tail:tt)*)? ) => ($(h!($($Tail)*);)?$( impl<$Hd $(, $Tail)*> Head for ($Hd, $($Tail),*) { type Head = $Hd; type Tail = ($($Tail, )*); fn ht($Hd: Self::Head, ($($Tail, )*): Self::Tail) -> Self { ($Hd, $($Tail),*) } })?)} h![_13 _12 _11 _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 _0]; muiua::i! { r#" t ← ⍣/◇⊂₃"" @\s ⍚$"\__," ⇡+1 impl ← ( ⊃(t|t|t-1|∘|t-1|t|t-1) $$ impl<_> Last for (_) { $$ type Init = (_); $$ type Last = \__; $$ fn il((_): Self::Init, last: Self::Last) -> (_) { $$ (_ last,) $$ } $$ } ) /◇⊂₃ @\n ⍚impl ⇡14 "# } impl + Sized> Bind for F {} pub trait Bind: FnMut + Sized { fn bind(self, with: T) -> impl FnMut where Args: Head, { return Fn { f: self, t: with }; struct Fn> { f: F, t: Args::Head, } impl> FnOnce for Fn { type Output = F::Output; extern "rust-call" fn call_once(mut self, args: Args::Tail) -> Self::Output { let args = Args::ht(self.t, args); self.f.call_mut(args) } } impl, F: FnMut> FnMut for Fn { extern "rust-call" fn call_mut(&mut self, args: Args::Tail) -> Self::Output { let args = Args::ht(self.t.clone(), args); self.f.call_mut(args) } } } fn rbind(self, with: T) -> impl FnMut where Args: Last, { return Fn { f: self, t: with }; struct Fn> { f: F, t: Args::Last, } impl> FnOnce for Fn { 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, F: FnMut> FnMut for Fn { 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) } } } } pub trait Compose { fn compose(self, other: impl FnMut(T) -> I) -> impl FnMut(T) -> R; } impl R> Compose for F { fn compose(mut self, mut other: impl FnMut(T) -> I) -> impl FnMut(T) -> R { move |x| self(other(x)) } }