1use crate::category::Category;
5
6pub trait Arrow: Category {
14 fn arr<A: Clone + 'static, B: Clone + 'static>(f: impl Fn(A) -> B + 'static) -> Self::P<A, B>;
16
17 fn first<A: Clone + 'static, B: Clone + 'static, C: Clone + 'static>(
19 pab: Self::P<A, B>,
20 ) -> Self::P<(A, C), (B, C)>;
21
22 fn second<A: Clone + 'static, B: Clone + 'static, C: Clone + 'static>(
24 pab: Self::P<A, B>,
25 ) -> Self::P<(C, A), (C, B)> {
26 let swap_in = Self::arr(|(c, a): (C, A)| (a, c));
27 let swap_out = Self::arr(|(b, c): (B, C)| (c, b));
28 Self::compose(swap_out, Self::compose(Self::first(pab), swap_in))
29 }
30
31 fn split<A: Clone + 'static, B: Clone + 'static, C: Clone + 'static, D: Clone + 'static>(
33 f: Self::P<A, B>,
34 g: Self::P<C, D>,
35 ) -> Self::P<(A, C), (B, D)> {
36 Self::compose(Self::second(g), Self::first(f))
37 }
38
39 fn fanout<A: Clone + 'static, B: Clone + 'static, C: Clone + 'static>(
41 f: Self::P<A, B>,
42 g: Self::P<A, C>,
43 ) -> Self::P<A, (B, C)> {
44 let dup = Self::arr(move |a: A| {
45 let a2 = a.clone();
46 (a, a2)
47 });
48 Self::compose(Self::split(f, g), dup)
49 }
50}