1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#![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<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>
    where
        Args: Head<Head = T>,
    {
        return Fn { f: self, t: with };
        struct Fn<Args: Head, F: FnMut<Args>> {
            f: F,
            t: Args::Head,
        }
        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::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::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)
            }
        }
    }
}

pub trait Compose<I, R> {
    fn compose<T>(self, other: impl FnMut(T) -> I) -> impl FnMut(T) -> R;
}
impl<I, R, F: FnMut(I) -> R> Compose<I, R> for F {
    fn compose<T>(mut self, mut other: impl FnMut(T) -> I) -> impl FnMut(T) -> R {
        move |x| self(other(x))
    }
}