1use super::functions::*;
6use std::fmt;
7
8#[allow(dead_code)]
10pub struct ContM<R, A> {
11 pub(super) run_cont: Box<dyn FnOnce(Box<dyn FnOnce(A) -> R>) -> R>,
12}
13#[allow(dead_code)]
16pub struct CodensityM<M, A> {
17 run_codensity: Box<dyn FnOnce(Box<dyn FnOnce(A) -> M>) -> M>,
18}
19#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct Maybe<A>(pub Option<A>);
22impl<A> Maybe<A> {
23 pub fn just(a: A) -> Self {
25 Maybe(Some(a))
26 }
27 pub fn nothing() -> Self {
29 Maybe(None)
30 }
31 pub fn is_nothing(&self) -> bool {
33 self.0.is_none()
34 }
35 pub fn is_just(&self) -> bool {
37 self.0.is_some()
38 }
39 pub fn bind<B>(self, f: impl FnOnce(A) -> Maybe<B>) -> Maybe<B> {
41 match self.0 {
42 Some(a) => f(a),
43 None => Maybe(None),
44 }
45 }
46 pub fn fmap<B>(self, f: impl FnOnce(A) -> B) -> Maybe<B> {
48 Maybe(self.0.map(f))
49 }
50 pub fn into_option(self) -> Option<A> {
52 self.0
53 }
54 pub fn or_else(self, other: Maybe<A>) -> Maybe<A> {
56 if self.is_just() {
57 self
58 } else {
59 other
60 }
61 }
62}
63#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct Identity<A> {
66 pub value: A,
68}
69impl<A> Identity<A> {
70 pub fn pure(a: A) -> Self {
72 Identity { value: a }
73 }
74 pub fn bind<B>(self, f: impl FnOnce(A) -> Identity<B>) -> Identity<B> {
76 f(self.value)
77 }
78 pub fn map<B>(self, f: impl FnOnce(A) -> B) -> Identity<B> {
80 Identity {
81 value: f(self.value),
82 }
83 }
84 pub fn run(self) -> A {
86 self.value
87 }
88}
89#[allow(dead_code)]
92pub enum FreeM<A> {
93 Pure(A),
95 Free(Box<FreeM<A>>),
97}
98pub struct Reader<R, A> {
100 run_fn: Box<dyn FnOnce(&R) -> A>,
101}
102impl<R: 'static, A: 'static> Reader<R, A> {
103 pub fn new(f: impl FnOnce(&R) -> A + 'static) -> Self {
105 Reader {
106 run_fn: Box::new(f),
107 }
108 }
109 pub fn pure(a: A) -> Self
111 where
112 A: Clone,
113 {
114 Reader::new(move |_| a.clone())
115 }
116 pub fn bind<B: 'static>(self, f: impl FnOnce(A) -> Reader<R, B> + 'static) -> Reader<R, B> {
118 Reader::new(move |r| {
119 let a = (self.run_fn)(r);
120 (f(a).run_fn)(r)
121 })
122 }
123 pub fn map<B: 'static>(self, f: impl FnOnce(A) -> B + 'static) -> Reader<R, B> {
125 Reader::new(move |r| f((self.run_fn)(r)))
126 }
127 pub fn run(self, env: &R) -> A {
129 (self.run_fn)(env)
130 }
131 pub fn ask() -> Reader<R, R>
133 where
134 R: Clone,
135 {
136 Reader::new(|r: &R| r.clone())
137 }
138 pub fn asks<B: 'static>(f: impl FnOnce(&R) -> B + 'static) -> Reader<R, B> {
140 Reader::new(f)
141 }
142}
143#[derive(Debug, Clone)]
145pub struct Writer<W, A> {
146 pub value: A,
148 pub log: W,
150}
151impl<W: Default + Extend<W::Item>, A> Writer<W, A>
152where
153 W: IntoIterator + Clone,
154{
155 pub fn pure(a: A) -> Self
157 where
158 W: Default,
159 {
160 Writer {
161 value: a,
162 log: W::default(),
163 }
164 }
165}
166impl<A> Writer<Vec<String>, A> {
167 pub fn new(value: A, log: Vec<String>) -> Self {
169 Writer { value, log }
170 }
171 pub fn bind<B>(self, f: impl FnOnce(A) -> Writer<Vec<String>, B>) -> Writer<Vec<String>, B> {
173 let Writer {
174 value: a,
175 log: log1,
176 } = self;
177 let mut log1 = log1;
178 let Writer {
179 value: b,
180 log: log2,
181 } = f(a);
182 log1.extend(log2);
183 Writer {
184 value: b,
185 log: log1,
186 }
187 }
188 pub fn fmap<B>(self, f: impl FnOnce(A) -> B) -> Writer<Vec<String>, B> {
190 Writer {
191 value: f(self.value),
192 log: self.log,
193 }
194 }
195 pub fn tell(msg: String) -> Writer<Vec<String>, ()> {
197 Writer {
198 value: (),
199 log: vec![msg],
200 }
201 }
202 pub fn into_log(self) -> Vec<String> {
204 self.log
205 }
206 pub fn into_value(self) -> A {
208 self.value
209 }
210}
211#[allow(dead_code)]
214pub struct IxState<I, J, A> {
215 pub(super) run_ix_state: Box<dyn FnOnce(I) -> (A, J)>,
216}
217#[derive(Debug, Clone, PartialEq, Eq)]
219pub struct Either<E, A> {
220 inner: Result<A, E>,
221}
222impl<E, A> Either<E, A> {
223 pub fn right(a: A) -> Self {
225 Either { inner: Ok(a) }
226 }
227 pub fn left(e: E) -> Self {
229 Either { inner: Err(e) }
230 }
231 pub fn is_right(&self) -> bool {
233 self.inner.is_ok()
234 }
235 pub fn is_left(&self) -> bool {
237 self.inner.is_err()
238 }
239 pub fn bind<B>(self, f: impl FnOnce(A) -> Either<E, B>) -> Either<E, B> {
241 match self.inner {
242 Ok(a) => f(a),
243 Err(e) => Either::left(e),
244 }
245 }
246 pub fn fmap<B>(self, f: impl FnOnce(A) -> B) -> Either<E, B> {
248 Either {
249 inner: self.inner.map(f),
250 }
251 }
252 pub fn map_left<F2>(self, f: impl FnOnce(E) -> F2) -> Either<F2, A> {
254 Either {
255 inner: self.inner.map_err(f),
256 }
257 }
258 pub fn into_result(self) -> Result<A, E> {
260 self.inner
261 }
262 pub fn unwrap_right(self) -> A
264 where
265 E: std::fmt::Debug,
266 {
267 self.inner
268 .expect("Either::unwrap_right called on Left variant")
269 }
270}
271pub struct State<S, A> {
273 run_fn: Box<dyn FnOnce(S) -> (A, S)>,
274}
275impl<S: 'static, A: 'static> State<S, A> {
276 pub fn new(f: impl FnOnce(S) -> (A, S) + 'static) -> Self {
278 State {
279 run_fn: Box::new(f),
280 }
281 }
282 pub fn pure(a: A) -> Self
284 where
285 A: Clone,
286 {
287 State::new(move |s| (a.clone(), s))
288 }
289 pub fn bind<B: 'static>(self, f: impl FnOnce(A) -> State<S, B> + 'static) -> State<S, B> {
291 State::new(move |s| {
292 let (a, s2) = (self.run_fn)(s);
293 (f(a).run_fn)(s2)
294 })
295 }
296 pub fn map<B: 'static>(self, f: impl FnOnce(A) -> B + 'static) -> State<S, B> {
298 State::new(move |s| {
299 let (a, s2) = (self.run_fn)(s);
300 (f(a), s2)
301 })
302 }
303 pub fn run(self, initial: S) -> (A, S) {
305 (self.run_fn)(initial)
306 }
307 pub fn eval(self, initial: S) -> A {
309 self.run(initial).0
310 }
311 pub fn exec(self, initial: S) -> S {
313 self.run(initial).1
314 }
315 pub fn get() -> State<S, S>
317 where
318 S: Clone,
319 {
320 State::new(|s: S| {
321 let s2 = s.clone();
322 (s2, s)
323 })
324 }
325 pub fn put(new_s: S) -> State<S, ()>
327 where
328 S: 'static,
329 {
330 State::new(move |_| ((), new_s))
331 }
332 pub fn modify(f: impl FnOnce(S) -> S + 'static) -> State<S, ()> {
334 State::new(move |s| ((), f(s)))
335 }
336}
337#[allow(dead_code)]
340pub struct ArrowF<A, B> {
341 pub(super) run_arrow: Box<dyn FnOnce(A) -> B>,
342}