Skip to main content

alice/core/
morphism.rs

1use alloc::boxed::Box;
2
3pub trait Morphism {
4    type Domain: Clone;
5    type Codomain: Clone;
6
7    fn apply(&self, x: &Self::Domain) -> Self::Codomain;
8}
9
10pub trait Composable<M>: Morphism
11where
12    M: Morphism<Codomain = Self::Domain>,
13{
14    type Composed: Morphism<Domain = M::Domain, Codomain = Self::Codomain>;
15    fn compose(self, other: M) -> Self::Composed;
16}
17
18pub trait Invertible: Morphism {
19    type Inverse: Morphism<Domain = Self::Codomain, Codomain = Self::Domain>;
20    fn inverse(self) -> Self::Inverse;
21}
22
23pub struct MapMorphism<A, B> {
24    f: Box<dyn Fn(&A) -> B + Send + Sync>,
25}
26
27impl<A: Clone, B: Clone> MapMorphism<A, B> {
28    pub fn new<F>(f: F) -> Self
29    where
30        F: Fn(&A) -> B + Send + Sync + 'static,
31    {
32        Self { f: Box::new(f) }
33    }
34}
35
36impl<A: Clone, B: Clone> Morphism for MapMorphism<A, B> {
37    type Domain = A;
38    type Codomain = B;
39
40    fn apply(&self, x: &A) -> B {
41        (self.f)(x)
42    }
43}
44
45pub struct ComposedMorphism<F, G> {
46    outer: F,
47    inner: G,
48}
49
50impl<F, G> Morphism for ComposedMorphism<F, G>
51where
52    F: Morphism,
53    G: Morphism<Codomain = F::Domain>,
54{
55    type Domain = G::Domain;
56    type Codomain = F::Codomain;
57
58    fn apply(&self, x: &Self::Domain) -> Self::Codomain {
59        let intermediate = self.inner.apply(x);
60        self.outer.apply(&intermediate)
61    }
62}
63
64impl<F, G> Composable<G> for F
65where
66    F: Morphism,
67    G: Morphism<Codomain = F::Domain>,
68{
69    type Composed = ComposedMorphism<F, G>;
70
71    fn compose(self, other: G) -> Self::Composed {
72        ComposedMorphism {
73            outer: self,
74            inner: other,
75        }
76    }
77}
78
79pub struct IdentityMorphism<A> {
80    _marker: core::marker::PhantomData<A>,
81}
82
83impl<A> IdentityMorphism<A> {
84    pub fn new() -> Self {
85        Self {
86            _marker: core::marker::PhantomData,
87        }
88    }
89}
90
91impl<A> Default for IdentityMorphism<A> {
92    fn default() -> Self {
93        Self::new()
94    }
95}
96
97impl<A: Clone> Morphism for IdentityMorphism<A> {
98    type Domain = A;
99    type Codomain = A;
100
101    fn apply(&self, x: &A) -> A {
102        x.clone()
103    }
104}
105
106impl<A: Clone> Invertible for IdentityMorphism<A> {
107    type Inverse = IdentityMorphism<A>;
108
109    fn inverse(self) -> Self::Inverse {
110        Self::new()
111    }
112}