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
use core::marker::PhantomData;
use super::{F1Once, F1};
pub struct Compose<F, G, X> {
  f: F,
  g: G,
  hidden_type: PhantomData<X>,
}
impl<F, G, X> Compose<F, G, X> {
  pub fn compose<A, B>(f: F, g: G) -> Self
    where F: F1Once<A, Ret = X>,
          G: F1Once<X, Ret = B>
  {
    Self { f,
           g,
           hidden_type: PhantomData }
  }
  pub fn chain<A, B, X2, G2>(self, g2: G2) -> Compose<Compose<F, G, X>, G2, X2>
    where F: F1Once<A, Ret = X>,
          G: F1Once<X, Ret = X2>,
          G2: F1Once<X2, Ret = B>
  {
    Compose { f: self,
              g: g2,
              hidden_type: PhantomData }
  }
}
impl<F, G, A, X, C> F1Once<A> for Compose<F, G, X>
  where F: F1Once<A, Ret = X>,
        G: F1Once<X, Ret = C>
{
  type Ret = C;
  fn call1(self, a: A) -> C {
    self.g.call1(self.f.call1(a))
  }
}
impl<F, G, A, X, C> F1<A> for Compose<F, G, X>
  where F: F1<A, Ret = X>,
        G: F1<X, Ret = C>
{
  fn call(&self, a: A) -> C {
    self.g.call(self.f.call(a))
  }
}