oxilean_std/functor/
types.rs1use super::functions::*;
5
6pub struct VecFunctor<A>(pub Vec<A>);
8pub struct Writer<A, W> {
12 value: A,
13 log: W,
14}
15impl<A, W: Default + Clone> Writer<A, W> {
16 pub fn new(value: A, log: W) -> Self {
18 Self { value, log }
19 }
20 pub fn pure(value: A) -> Self {
22 Self {
23 value,
24 log: W::default(),
25 }
26 }
27 pub fn get_value(self) -> A {
29 self.value
30 }
31 pub fn get_log(&self) -> &W {
33 &self.log
34 }
35 pub fn run(self) -> (A, W) {
37 (self.value, self.log)
38 }
39}
40#[allow(dead_code)]
42pub struct DayConvolution<F, G, A> {
43 pub left: F,
45 pub right: G,
47 pub _phantom: std::marker::PhantomData<A>,
49}
50#[allow(dead_code)]
52pub struct RepresentableFunctorExt<A> {
53 pub table: Vec<A>,
55}
56impl<A: Clone> RepresentableFunctorExt<A> {
57 pub fn tabulate(n: usize, f: impl Fn(usize) -> A) -> Self {
59 Self {
60 table: (0..n).map(f).collect(),
61 }
62 }
63 pub fn index(&self, i: usize) -> Option<&A> {
65 self.table.get(i)
66 }
67}
68pub struct ResultFunctor<A, E>(pub Result<A, E>);
70pub struct Reader<E, A> {
74 run: Box<dyn Fn(E) -> A>,
75}
76impl<E: Clone + 'static, A: 'static> Reader<E, A> {
77 pub fn new(f: impl Fn(E) -> A + 'static) -> Self {
79 Self { run: Box::new(f) }
80 }
81 pub fn run_reader(self, env: E) -> A {
83 (self.run)(env)
84 }
85 pub fn map<B: 'static>(self, f: impl Fn(A) -> B + 'static) -> Reader<E, B> {
87 let run = self.run;
88 Reader::new(move |env: E| f(run(env)))
89 }
90 pub fn pure(a: A) -> Self
92 where
93 A: Clone,
94 {
95 Reader::new(move |_| a.clone())
96 }
97}
98#[allow(dead_code)]
100pub struct ContravariantFunctor<A> {
101 pub predicate: Box<dyn Fn(A) -> bool>,
103}
104pub struct Pred<A>(pub Box<dyn Fn(A) -> bool>);
106impl<A> Pred<A> {
107 pub fn new(f: impl Fn(A) -> bool + 'static) -> Self {
109 Pred(Box::new(f))
110 }
111 pub fn test(&self, a: A) -> bool {
113 (self.0)(a)
114 }
115}
116impl<A: 'static> Pred<A> {
117 pub fn contramap<B, F: Fn(B) -> A + 'static>(self, f: F) -> Pred<B> {
119 Pred(Box::new(move |b| (self.0)(f(b))))
120 }
121}
122#[allow(dead_code)]
124pub struct ProfunctorCompose<A, B, C> {
125 pub left: Box<dyn Fn(A) -> B>,
127 pub right: Box<dyn Fn(B) -> C>,
129}
130#[derive(Clone, Debug, PartialEq, Eq)]
132pub enum Either<A, B> {
133 Left(A),
135 Right(B),
137}
138impl<A, B> Either<A, B> {
139 pub fn is_left(&self) -> bool {
141 matches!(self, Either::Left(_))
142 }
143 pub fn is_right(&self) -> bool {
145 matches!(self, Either::Right(_))
146 }
147 pub fn unwrap_left(self) -> A {
149 match self {
150 Either::Left(a) => a,
151 _ => panic!("Right"),
152 }
153 }
154 pub fn unwrap_right(self) -> B {
156 match self {
157 Either::Right(b) => b,
158 _ => panic!("Left"),
159 }
160 }
161 pub fn map_left<C, F: FnOnce(A) -> C>(self, f: F) -> Either<C, B> {
163 match self {
164 Either::Left(a) => Either::Left(f(a)),
165 Either::Right(b) => Either::Right(b),
166 }
167 }
168 pub fn map_right<D, G: FnOnce(B) -> D>(self, g: G) -> Either<A, D> {
170 match self {
171 Either::Left(a) => Either::Left(a),
172 Either::Right(b) => Either::Right(g(b)),
173 }
174 }
175 pub fn bimap<C, D, F: FnOnce(A) -> C, G: FnOnce(B) -> D>(self, f: F, g: G) -> Either<C, D> {
177 match self {
178 Either::Left(a) => Either::Left(f(a)),
179 Either::Right(b) => Either::Right(g(b)),
180 }
181 }
182 pub fn left(self) -> Option<A> {
184 match self {
185 Either::Left(a) => Some(a),
186 _ => None,
187 }
188 }
189 pub fn right(self) -> Option<B> {
191 match self {
192 Either::Right(b) => Some(b),
193 _ => None,
194 }
195 }
196}
197pub struct OptionFunctor<A>(pub Option<A>);
199#[allow(dead_code)]
201pub struct FunctorCompose<F, G, A> {
202 pub outer: F,
204 pub inner: G,
206 pub _phantom: std::marker::PhantomData<A>,
208}