1use core::marker::PhantomData;
2
3use super::{F1Once, F1};
4
5pub struct Compose<F, G, X> {
16 f: F,
17 g: G,
18 hidden_type: PhantomData<X>,
19}
20
21impl<F, G, X> Compose<F, G, X> {
22 pub fn compose<A, B>(f: F, g: G) -> Self
24 where F: F1Once<A, Ret = X>,
25 G: F1Once<X, Ret = B>
26 {
27 Self { f,
28 g,
29 hidden_type: PhantomData }
30 }
31
32 pub fn chain<A, B, X2, G2>(self, g2: G2) -> Compose<Compose<F, G, X>, G2, X2>
34 where F: F1Once<A, Ret = X>,
35 G: F1Once<X, Ret = X2>,
36 G2: F1Once<X2, Ret = B>
37 {
38 Compose { f: self,
39 g: g2,
40 hidden_type: PhantomData }
41 }
42}
43
44impl<F, G, A, X, C> F1Once<A> for Compose<F, G, X>
45 where F: F1Once<A, Ret = X>,
46 G: F1Once<X, Ret = C>
47{
48 type Ret = C;
49 fn call1(self, a: A) -> C {
50 self.g.call1(self.f.call1(a))
51 }
52}
53
54impl<F, G, A, X, C> F1<A> for Compose<F, G, X>
55 where F: F1<A, Ret = X>,
56 G: F1<X, Ret = C>
57{
58 fn call(&self, a: A) -> C {
59 self.g.call(self.f.call(a))
60 }
61}