fp_library/types/result.rs
1use crate::{
2 Apply,
3 brands::{ResultBrand, ResultWithErrBrand, ResultWithOkBrand},
4 classes::{
5 applicative::Applicative, apply_first::ApplyFirst, apply_second::ApplySecond,
6 bifunctor::Bifunctor, cloneable_fn::CloneableFn, foldable::Foldable, functor::Functor,
7 lift::Lift, monoid::Monoid, par_foldable::ParFoldable, pointed::Pointed,
8 semiapplicative::Semiapplicative, semimonad::Semimonad, send_cloneable_fn::SendCloneableFn,
9 traversable::Traversable,
10 },
11 impl_kind,
12 kinds::*,
13};
14
15impl_kind! {
16 for ResultBrand {
17 type Of<A, B> = Result<B, A>;
18 }
19}
20
21impl_kind! {
22 for ResultBrand {
23 type Of<'a, A: 'a, B: 'a>: 'a = Result<B, A>;
24 }
25}
26
27impl Bifunctor for ResultBrand {
28 /// Maps functions over the values in the result.
29 ///
30 /// This method applies one function to the error value and another to the success value.
31 ///
32 /// ### Type Signature
33 ///
34 /// `forall a b c d. Bifunctor Result => (a -> b, c -> d, Result c a) -> Result d b`
35 ///
36 /// ### Type Parameters
37 ///
38 /// * `A`: The type of the error value.
39 /// * `B`: The type of the mapped error value.
40 /// * `C`: The type of the success value.
41 /// * `D`: The type of the mapped success value.
42 /// * `F`: The type of the function to apply to the error.
43 /// * `G`: The type of the function to apply to the success.
44 ///
45 /// ### Parameters
46 ///
47 /// * `f`: The function to apply to the error.
48 /// * `g`: The function to apply to the success.
49 /// * `p`: The result to map over.
50 ///
51 /// ### Returns
52 ///
53 /// A new result containing the mapped values.
54 ///
55 /// ### Examples
56 ///
57 /// ```
58 /// use fp_library::{brands::*, classes::bifunctor::*, functions::*};
59 ///
60 /// let x: Result<i32, i32> = Ok(5);
61 /// assert_eq!(bimap::<ResultBrand, _, _, _, _, _, _>(|e| e + 1, |s| s * 2, x), Ok(10));
62 ///
63 /// let y: Result<i32, i32> = Err(5);
64 /// assert_eq!(bimap::<ResultBrand, _, _, _, _, _, _>(|e| e + 1, |s| s * 2, y), Err(6));
65 /// ```
66 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a, F, G>(
67 f: F,
68 g: G,
69 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
70 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>)
71 where
72 F: Fn(A) -> B + 'a,
73 G: Fn(C) -> D + 'a,
74 {
75 match p {
76 Ok(c) => Ok(g(c)),
77 Err(a) => Err(f(a)),
78 }
79 }
80}
81
82// ResultWithErrBrand<E> (Functor over T)
83
84impl_kind! {
85 impl<E: 'static> for ResultWithErrBrand<E> {
86 type Of<'a, A: 'a>: 'a = Result<A, E>;
87 }
88}
89
90impl<E: 'static> Functor for ResultWithErrBrand<E> {
91 /// Maps a function over the value in the result.
92 ///
93 /// This method applies a function to the value inside the result if it is `Ok`, producing a new result with the transformed value. If the result is `Err`, it is returned unchanged.
94 ///
95 /// ### Type Signature
96 ///
97 /// `forall e b a. Functor (Result e) => (a -> b, Result a e) -> Result b e`
98 ///
99 /// ### Type Parameters
100 ///
101 /// * `B`: The type of the result of applying the function.
102 /// * `A`: The type of the value inside the result.
103 /// * `F`: The type of the function to apply.
104 ///
105 /// ### Parameters
106 ///
107 /// * `f`: The function to apply.
108 /// * `fa`: The result to map over.
109 ///
110 /// ### Returns
111 ///
112 /// A new result containing the result of applying the function, or the original error.
113 ///
114 /// ### Examples
115 ///
116 /// ```
117 /// use fp_library::functions::*;
118 /// use fp_library::brands::ResultWithErrBrand;
119 ///
120 /// assert_eq!(map::<ResultWithErrBrand<()>, _, _, _>(|x: i32| x * 2, Ok(5)), Ok(10));
121 /// assert_eq!(map::<ResultWithErrBrand<i32>, _, _, _>(|x: i32| x * 2, Err(1)), Err(1));
122 /// ```
123 fn map<'a, B: 'a, A: 'a, F>(
124 f: F,
125 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
126 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
127 where
128 F: Fn(A) -> B + 'a,
129 {
130 fa.map(f)
131 }
132}
133
134impl<E: Clone + 'static> Lift for ResultWithErrBrand<E> {
135 /// Lifts a binary function into the result context.
136 ///
137 /// This method lifts a binary function to operate on values within the result context.
138 ///
139 /// ### Type Signature
140 ///
141 /// `forall e c a b. Lift (Result e) => ((a, b) -> c, Result a e, Result b e) -> Result c e`
142 ///
143 /// ### Type Parameters
144 ///
145 /// * `C`: The type of the result.
146 /// * `A`: The type of the first value.
147 /// * `B`: The type of the second value.
148 /// * `F`: The type of the binary function.
149 ///
150 /// ### Parameters
151 ///
152 /// * `f`: The binary function to apply.
153 /// * `fa`: The first result.
154 /// * `fb`: The second result.
155 ///
156 /// ### Returns
157 ///
158 /// `Ok(f(a, b))` if both results are `Ok`, otherwise the first error encountered.
159 ///
160 /// ### Examples
161 ///
162 /// ```
163 /// use fp_library::functions::*;
164 /// use fp_library::brands::ResultWithErrBrand;
165 ///
166 /// assert_eq!(
167 /// lift2::<ResultWithErrBrand<()>, _, _, _, _>(|x: i32, y: i32| x + y, Ok(1), Ok(2)),
168 /// Ok(3)
169 /// );
170 /// assert_eq!(
171 /// lift2::<ResultWithErrBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Ok(1), Err(2)),
172 /// Err(2)
173 /// );
174 /// assert_eq!(
175 /// lift2::<ResultWithErrBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Err(1), Ok(2)),
176 /// Err(1)
177 /// );
178 /// assert_eq!(
179 /// lift2::<ResultWithErrBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Err(1), Err(2)),
180 /// Err(1)
181 /// );
182 /// ```
183 fn lift2<'a, C, A, B, F>(
184 f: F,
185 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
186 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
187 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
188 where
189 F: Fn(A, B) -> C + 'a,
190 A: Clone + 'a,
191 B: Clone + 'a,
192 C: 'a,
193 {
194 match (fa, fb) {
195 (Ok(a), Ok(b)) => Ok(f(a, b)),
196 (Err(e), _) => Err(e),
197 (_, Err(e)) => Err(e),
198 }
199 }
200}
201
202impl<E: 'static> Pointed for ResultWithErrBrand<E> {
203 /// Wraps a value in a result.
204 ///
205 /// This method wraps a value in the `Ok` variant of a `Result`.
206 ///
207 /// ### Type Signature
208 ///
209 /// `forall e a. Pointed (Result e) => a -> Result a e`
210 ///
211 /// ### Type Parameters
212 ///
213 /// * `A`: The type of the value to wrap.
214 ///
215 /// ### Parameters
216 ///
217 /// * `a`: The value to wrap.
218 ///
219 /// ### Returns
220 ///
221 /// `Ok(a)`.
222 ///
223 /// ### Examples
224 ///
225 /// ```
226 /// use fp_library::functions::*;
227 /// use fp_library::brands::ResultWithErrBrand;
228 ///
229 /// assert_eq!(pure::<ResultWithErrBrand<()>, _>(5), Ok(5));
230 /// ```
231 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
232 Ok(a)
233 }
234}
235
236impl<E: Clone + 'static> ApplyFirst for ResultWithErrBrand<E> {}
237impl<E: Clone + 'static> ApplySecond for ResultWithErrBrand<E> {}
238
239impl<E: Clone + 'static> Semiapplicative for ResultWithErrBrand<E> {
240 /// Applies a wrapped function to a wrapped value.
241 ///
242 /// This method applies a function wrapped in a result to a value wrapped in a result.
243 ///
244 /// ### Type Signature
245 ///
246 /// `forall fn_brand e b a. Semiapplicative (Result e) => (Result (fn_brand a b) e, Result a e) -> Result b e`
247 ///
248 /// ### Type Parameters
249 ///
250 /// * `FnBrand`: The brand of the cloneable function wrapper.
251 /// * `B`: The type of the output value.
252 /// * `A`: The type of the input value.
253 ///
254 /// ### Parameters
255 ///
256 /// * `ff`: The result containing the function.
257 /// * `fa`: The result containing the value.
258 ///
259 /// ### Returns
260 ///
261 /// `Ok(f(a))` if both are `Ok`, otherwise the first error encountered.
262 ///
263 /// ### Examples
264 ///
265 /// ```
266 /// use fp_library::{brands::*, classes::*, functions::*, Apply, Kind};
267 ///
268 /// let f: Result<_, ()> = Ok(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
269 /// assert_eq!(apply::<RcFnBrand, ResultWithErrBrand<()>, _, _>(f, Ok(5)), Ok(10));
270 /// let f: Result<_, i32> = Ok(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
271 /// assert_eq!(apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(f, Err(1)), Err(1));
272 ///
273 /// let f_err: Result<_, i32> = Err(1);
274 /// assert_eq!(apply::<RcFnBrand, ResultWithErrBrand<i32>, i32, i32>(f_err, Ok(5)), Err(1));
275 /// ```
276 fn apply<'a, FnBrand: 'a + CloneableFn, B: 'a, A: 'a + Clone>(
277 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
278 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
279 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
280 match (ff, fa) {
281 (Ok(f), Ok(a)) => Ok(f(a)),
282 (Err(e), _) => Err(e),
283 (_, Err(e)) => Err(e),
284 }
285 }
286}
287
288impl<E: Clone + 'static> Semimonad for ResultWithErrBrand<E> {
289 /// Chains result computations.
290 ///
291 /// This method chains two computations, where the second computation depends on the result of the first.
292 ///
293 /// ### Type Signature
294 ///
295 /// `forall e b a. Semimonad (Result e) => (Result a e, a -> Result b e) -> Result b e`
296 ///
297 /// ### Type Parameters
298 ///
299 /// * `B`: The type of the result of the second computation.
300 /// * `A`: The type of the result of the first computation.
301 /// * `F`: The type of the function to apply.
302 ///
303 /// ### Parameters
304 ///
305 /// * `ma`: The first result.
306 /// * `f`: The function to apply to the value inside the result.
307 ///
308 /// ### Returns
309 ///
310 /// The result of applying `f` to the value if `ma` is `Ok`, otherwise the original error.
311 ///
312 /// ### Examples
313 ///
314 /// ```
315 /// use fp_library::functions::*;
316 /// use fp_library::brands::ResultWithErrBrand;
317 ///
318 /// assert_eq!(
319 /// bind::<ResultWithErrBrand<()>, _, _, _>(Ok(5), |x| Ok(x * 2)),
320 /// Ok(10)
321 /// );
322 /// assert_eq!(
323 /// bind::<ResultWithErrBrand<i32>, _, _, _>(Ok(5), |_| Err::<i32, _>(1)),
324 /// Err(1)
325 /// );
326 /// assert_eq!(
327 /// bind::<ResultWithErrBrand<i32>, _, _, _>(Err(1), |x: i32| Ok(x * 2)),
328 /// Err(1)
329 /// );
330 /// ```
331 fn bind<'a, B: 'a, A: 'a, F>(
332 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
333 f: F,
334 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
335 where
336 F: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
337 {
338 ma.and_then(f)
339 }
340}
341
342impl<E: 'static> Foldable for ResultWithErrBrand<E> {
343 /// Folds the result from the right.
344 ///
345 /// This method performs a right-associative fold of the result.
346 ///
347 /// ### Type Signature
348 ///
349 /// `forall e b a. Foldable (Result e) => ((a, b) -> b, b, Result a e) -> b`
350 ///
351 /// ### Type Parameters
352 ///
353 /// * `FnBrand`: The brand of the cloneable function to use.
354 /// * `B`: The type of the accumulator.
355 /// * `A`: The type of the elements in the structure.
356 /// * `F`: The type of the folding function.
357 ///
358 /// ### Parameters
359 ///
360 /// * `func`: The folding function.
361 /// * `initial`: The initial value.
362 /// * `fa`: The result to fold.
363 ///
364 /// ### Returns
365 ///
366 /// `func(a, initial)` if `fa` is `Ok(a)`, otherwise `initial`.
367 ///
368 /// ### Examples
369 ///
370 /// ```
371 /// use fp_library::functions::*;
372 /// use fp_library::brands::{ResultWithErrBrand, RcFnBrand};
373 ///
374 /// assert_eq!(fold_right::<RcFnBrand, ResultWithErrBrand<()>, _, _, _>(|x, acc| x + acc, 0, Ok(5)), 5);
375 /// assert_eq!(fold_right::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(|x: i32, acc| x + acc, 0, Err(1)), 0);
376 /// ```
377 fn fold_right<'a, FnBrand, B: 'a, A: 'a, F>(
378 func: F,
379 initial: B,
380 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
381 ) -> B
382 where
383 F: Fn(A, B) -> B + 'a,
384 FnBrand: CloneableFn + 'a,
385 {
386 match fa {
387 Ok(a) => func(a, initial),
388 Err(_) => initial,
389 }
390 }
391
392 /// Folds the result from the left.
393 ///
394 /// This method performs a left-associative fold of the result.
395 ///
396 /// ### Type Signature
397 ///
398 /// `forall e b a. Foldable (Result e) => ((b, a) -> b, b, Result a e) -> b`
399 ///
400 /// ### Type Parameters
401 ///
402 /// * `FnBrand`: The brand of the cloneable function to use.
403 /// * `B`: The type of the accumulator.
404 /// * `A`: The type of the elements in the structure.
405 /// * `F`: The type of the folding function.
406 ///
407 /// ### Parameters
408 ///
409 /// * `func`: The folding function.
410 /// * `initial`: The initial value.
411 /// * `fa`: The result to fold.
412 ///
413 /// ### Returns
414 ///
415 /// `func(initial, a)` if `fa` is `Ok(a)`, otherwise `initial`.
416 ///
417 /// ### Examples
418 ///
419 /// ```
420 /// use fp_library::functions::*;
421 /// use fp_library::brands::{ResultWithErrBrand, RcFnBrand};
422 ///
423 /// assert_eq!(fold_left::<RcFnBrand, ResultWithErrBrand<()>, _, _, _>(|acc, x| acc + x, 0, Ok(5)), 5);
424 /// assert_eq!(fold_left::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(|acc, x: i32| acc + x, 0, Err(1)), 0);
425 /// ```
426 fn fold_left<'a, FnBrand, B: 'a, A: 'a, F>(
427 func: F,
428 initial: B,
429 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
430 ) -> B
431 where
432 F: Fn(B, A) -> B + 'a,
433 FnBrand: CloneableFn + 'a,
434 {
435 match fa {
436 Ok(a) => func(initial, a),
437 Err(_) => initial,
438 }
439 }
440
441 /// Maps the value to a monoid and returns it.
442 ///
443 /// This method maps the element of the result to a monoid and then returns it.
444 ///
445 /// ### Type Signature
446 ///
447 /// `forall e m a. (Foldable (Result e), Monoid m) => ((a) -> m, Result a e) -> m`
448 ///
449 /// ### Type Parameters
450 ///
451 /// * `FnBrand`: The brand of the cloneable function to use.
452 /// * `M`: The type of the monoid.
453 /// * `A`: The type of the elements in the structure.
454 /// * `F`: The type of the mapping function.
455 ///
456 /// ### Parameters
457 ///
458 /// * `func`: The mapping function.
459 /// * `fa`: The result to fold.
460 ///
461 /// ### Returns
462 ///
463 /// `func(a)` if `fa` is `Ok(a)`, otherwise `M::empty()`.
464 ///
465 /// ### Examples
466 ///
467 /// ```
468 /// use fp_library::{brands::*, functions::*};
469 ///
470 /// assert_eq!(
471 /// fold_map::<RcFnBrand, ResultWithErrBrand<()>, _, _, _>(|x: i32| x.to_string(), Ok(5)),
472 /// "5".to_string()
473 /// );
474 /// assert_eq!(
475 /// fold_map::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(|x: i32| x.to_string(), Err(1)),
476 /// "".to_string()
477 /// );
478 /// ```
479 fn fold_map<'a, FnBrand, M, A: 'a, F>(
480 func: F,
481 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
482 ) -> M
483 where
484 M: Monoid + 'a,
485 F: Fn(A) -> M + 'a,
486 FnBrand: CloneableFn + 'a,
487 {
488 match fa {
489 Ok(a) => func(a),
490 Err(_) => M::empty(),
491 }
492 }
493}
494
495impl<E: Clone + 'static> Traversable for ResultWithErrBrand<E> {
496 /// Traverses the result with an applicative function.
497 ///
498 /// This method maps the element of the result to a computation, evaluates it, and combines the result into an applicative context.
499 ///
500 /// ### Type Signature
501 ///
502 /// `forall e f b a. (Traversable (Result e), Applicative f) => (a -> f b, Result a e) -> f (Result b e)`
503 ///
504 /// ### Type Parameters
505 ///
506 /// * `F`: The applicative context.
507 /// * `B`: The type of the elements in the resulting traversable structure.
508 /// * `A`: The type of the elements in the traversable structure.
509 /// * `Func`: The type of the function to apply.
510 ///
511 /// ### Parameters
512 ///
513 /// * `func`: The function to apply.
514 /// * `ta`: The result to traverse.
515 ///
516 /// ### Returns
517 ///
518 /// The result wrapped in the applicative context.
519 ///
520 /// ### Examples
521 ///
522 /// ```
523 /// use fp_library::functions::*;
524 /// use fp_library::brands::{ResultWithErrBrand, OptionBrand};
525 ///
526 /// assert_eq!(
527 /// traverse::<ResultWithErrBrand<()>, OptionBrand, _, _, _>(|x| Some(x * 2), Ok(5)),
528 /// Some(Ok(10))
529 /// );
530 /// assert_eq!(
531 /// traverse::<ResultWithErrBrand<i32>, OptionBrand, _, _, _>(|x: i32| Some(x * 2), Err(1)),
532 /// Some(Err(1))
533 /// );
534 /// assert_eq!(
535 /// traverse::<ResultWithErrBrand<()>, OptionBrand, _, _, _>(|_| None::<i32>, Ok(5)),
536 /// None
537 /// );
538 /// ```
539 fn traverse<'a, F: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
540 func: Func,
541 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
542 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
543 where
544 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
545 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
546 {
547 match ta {
548 Ok(a) => F::map(|b| Ok(b), func(a)),
549 Err(e) => F::pure(Err(e)),
550 }
551 }
552
553 /// Sequences a result of applicative.
554 ///
555 /// This method evaluates the computation inside the result and accumulates the result into an applicative context.
556 ///
557 /// ### Type Signature
558 ///
559 /// `forall e f a. (Traversable (Result e), Applicative f) => (Result (f a) e) -> f (Result a e)`
560 ///
561 /// ### Type Parameters
562 ///
563 /// * `F`: The applicative context.
564 /// * `A`: The type of the elements in the traversable structure.
565 ///
566 /// ### Parameters
567 ///
568 /// * `ta`: The result containing the applicative value.
569 ///
570 /// ### Returns
571 ///
572 /// The result wrapped in the applicative context.
573 ///
574 /// ### Examples
575 ///
576 /// ```
577 /// use fp_library::functions::*;
578 /// use fp_library::brands::{ResultWithErrBrand, OptionBrand};
579 ///
580 /// assert_eq!(
581 /// sequence::<ResultWithErrBrand<()>, OptionBrand, _>(Ok(Some(5))),
582 /// Some(Ok(5))
583 /// );
584 /// assert_eq!(
585 /// sequence::<ResultWithErrBrand<i32>, OptionBrand, i32>(Err::<Option<i32>, _>(1)),
586 /// Some(Err::<i32, i32>(1))
587 /// );
588 /// assert_eq!(
589 /// sequence::<ResultWithErrBrand<()>, OptionBrand, _>(Ok(None::<i32>)),
590 /// None
591 /// );
592 /// ```
593 fn sequence<'a, F: Applicative, A: 'a + Clone>(
594 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
595 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
596 where
597 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
598 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
599 {
600 match ta {
601 Ok(fa) => F::map(|a| Ok(a), fa),
602 Err(e) => F::pure(Err(e)),
603 }
604 }
605}
606
607// ResultWithOkBrand<T> (Functor over E)
608
609impl_kind! {
610 impl<T: 'static> for ResultWithOkBrand<T> {
611 type Of<'a, A: 'a>: 'a = Result<T, A>;
612 }
613}
614
615impl<T: 'static> Functor for ResultWithOkBrand<T> {
616 /// Maps a function over the error value in the result.
617 ///
618 /// This method applies a function to the error value inside the result if it is `Err`, producing a new result with the transformed error. If the result is `Ok`, it is returned unchanged.
619 ///
620 /// ### Type Signature
621 ///
622 /// `forall t b a. Functor (Result t) => (a -> b, Result t a) -> Result t b`
623 ///
624 /// ### Type Parameters
625 ///
626 /// * `B`: The type of the result of applying the function.
627 /// * `A`: The type of the error value inside the result.
628 /// * `F`: The type of the function to apply.
629 ///
630 /// ### Parameters
631 ///
632 /// * `f`: The function to apply to the error.
633 /// * `fa`: The result to map over.
634 ///
635 /// ### Returns
636 ///
637 /// A new result containing the mapped error, or the original success value.
638 ///
639 /// ### Examples
640 ///
641 /// ```
642 /// use fp_library::functions::*;
643 /// use fp_library::brands::ResultWithOkBrand;
644 ///
645 /// assert_eq!(map::<ResultWithOkBrand<i32>, _, _, _>(|x: i32| x * 2, Err(5)), Err(10));
646 /// assert_eq!(map::<ResultWithOkBrand<i32>, _, _, _>(|x: i32| x * 2, Ok(1)), Ok(1));
647 /// ```
648 fn map<'a, B: 'a, A: 'a, F>(
649 f: F,
650 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
651 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
652 where
653 F: Fn(A) -> B + 'a,
654 {
655 match fa {
656 Ok(t) => Ok(t),
657 Err(e) => Err(f(e)),
658 }
659 }
660}
661
662impl<T: Clone + 'static> Lift for ResultWithOkBrand<T> {
663 /// Lifts a binary function into the result context (over error).
664 ///
665 /// This method lifts a binary function to operate on error values within the result context.
666 ///
667 /// ### Type Signature
668 ///
669 /// `forall t c a b. Lift (Result t) => ((a, b) -> c, Result t a, Result t b) -> Result t c`
670 ///
671 /// ### Type Parameters
672 ///
673 /// * `C`: The type of the result error value.
674 /// * `A`: The type of the first error value.
675 /// * `B`: The type of the second error value.
676 /// * `F`: The type of the binary function.
677 ///
678 /// ### Parameters
679 ///
680 /// * `f`: The binary function to apply to the errors.
681 /// * `fa`: The first result.
682 /// * `fb`: The second result.
683 ///
684 /// ### Returns
685 ///
686 /// `Err(f(a, b))` if both results are `Err`, otherwise the first success encountered.
687 ///
688 /// ### Examples
689 ///
690 /// ```
691 /// use fp_library::functions::*;
692 /// use fp_library::brands::ResultWithOkBrand;
693 ///
694 /// assert_eq!(
695 /// lift2::<ResultWithOkBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Err(1), Err(2)),
696 /// Err(3)
697 /// );
698 /// assert_eq!(
699 /// lift2::<ResultWithOkBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Err(1), Ok(2)),
700 /// Ok(2)
701 /// );
702 /// assert_eq!(
703 /// lift2::<ResultWithOkBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Ok(1), Err(2)),
704 /// Ok(1)
705 /// );
706 /// assert_eq!(
707 /// lift2::<ResultWithOkBrand<i32>, _, _, _, _>(|x: i32, y: i32| x + y, Ok(1), Ok(2)),
708 /// Ok(1)
709 /// );
710 /// ```
711 fn lift2<'a, C, A, B, F>(
712 f: F,
713 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
714 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
715 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
716 where
717 F: Fn(A, B) -> C + 'a,
718 A: Clone + 'a,
719 B: Clone + 'a,
720 C: 'a,
721 {
722 match (fa, fb) {
723 (Err(a), Err(b)) => Err(f(a, b)),
724 (Ok(t), _) => Ok(t),
725 (_, Ok(t)) => Ok(t),
726 }
727 }
728}
729
730impl<T: 'static> Pointed for ResultWithOkBrand<T> {
731 /// Wraps a value in a result (as error).
732 ///
733 /// This method wraps a value in the `Err` variant of a `Result`.
734 ///
735 /// ### Type Signature
736 ///
737 /// `forall t a. Pointed (Result t) => a -> Result t a`
738 ///
739 /// ### Type Parameters
740 ///
741 /// * `A`: The type of the value to wrap.
742 ///
743 /// ### Parameters
744 ///
745 /// * `a`: The value to wrap.
746 ///
747 /// ### Returns
748 ///
749 /// `Err(a)`.
750 ///
751 /// ### Examples
752 ///
753 /// ```
754 /// use fp_library::functions::*;
755 /// use fp_library::brands::ResultWithOkBrand;
756 ///
757 /// assert_eq!(pure::<ResultWithOkBrand<()>, _>(5), Err(5));
758 /// ```
759 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
760 Err(a)
761 }
762}
763
764impl<T: Clone + 'static> ApplyFirst for ResultWithOkBrand<T> {}
765impl<T: Clone + 'static> ApplySecond for ResultWithOkBrand<T> {}
766
767impl<T: Clone + 'static> Semiapplicative for ResultWithOkBrand<T> {
768 /// Applies a wrapped function to a wrapped value (over error).
769 ///
770 /// This method applies a function wrapped in a result (as error) to a value wrapped in a result (as error).
771 ///
772 /// ### Type Signature
773 ///
774 /// `forall fn_brand t b a. Semiapplicative (Result t) => (Result t (fn_brand a b), Result t a) -> Result t b`
775 ///
776 /// ### Type Parameters
777 ///
778 /// * `FnBrand`: The brand of the cloneable function wrapper.
779 /// * `B`: The type of the output value.
780 /// * `A`: The type of the input value.
781 ///
782 /// ### Parameters
783 ///
784 /// * `ff`: The result containing the function (in Err).
785 /// * `fa`: The result containing the value (in Err).
786 ///
787 /// ### Returns
788 ///
789 /// `Err(f(a))` if both are `Err`, otherwise the first success encountered.
790 ///
791 /// ### Examples
792 ///
793 /// ```
794 /// use fp_library::{brands::*, classes::*, functions::*, Apply, Kind};
795 ///
796 /// let f: Result<(), _> = Err(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
797 /// assert_eq!(apply::<RcFnBrand, ResultWithOkBrand<()>, _, _>(f, Err(5)), Err(10));
798 /// let f: Result<i32, _> = Err(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
799 /// assert_eq!(apply::<RcFnBrand, ResultWithOkBrand<i32>, _, _>(f, Ok(1)), Ok(1));
800 ///
801 /// let f_ok: Result<i32, _> = Ok(1);
802 /// assert_eq!(apply::<RcFnBrand, ResultWithOkBrand<i32>, i32, i32>(f_ok, Err(5)), Ok(1));
803 /// ```
804 fn apply<'a, FnBrand: 'a + CloneableFn, B: 'a, A: 'a + Clone>(
805 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
806 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
807 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
808 match (ff, fa) {
809 (Err(f), Err(a)) => Err(f(a)),
810 (Ok(t), _) => Ok(t),
811 (_, Ok(t)) => Ok(t),
812 }
813 }
814}
815
816impl<T: Clone + 'static> Semimonad for ResultWithOkBrand<T> {
817 /// Chains result computations (over error).
818 ///
819 /// This method chains two computations, where the second computation depends on the result of the first (over error).
820 ///
821 /// ### Type Signature
822 ///
823 /// `forall t b a. Semimonad (Result t) => (Result t a, a -> Result t b) -> Result t b`
824 ///
825 /// ### Type Parameters
826 ///
827 /// * `B`: The type of the result of the second computation.
828 /// * `A`: The type of the result of the first computation.
829 /// * `F`: The type of the function to apply.
830 ///
831 /// ### Parameters
832 ///
833 /// * `ma`: The first result.
834 /// * `f`: The function to apply to the error value.
835 ///
836 /// ### Returns
837 ///
838 /// The result of applying `f` to the error if `ma` is `Err`, otherwise the original success.
839 ///
840 /// ### Examples
841 ///
842 /// ```
843 /// use fp_library::functions::*;
844 /// use fp_library::brands::ResultWithOkBrand;
845 ///
846 /// assert_eq!(
847 /// bind::<ResultWithOkBrand<()>, _, _, _>(Err(5), |x| Err(x * 2)),
848 /// Err(10)
849 /// );
850 /// assert_eq!(
851 /// bind::<ResultWithOkBrand<i32>, _, _, _>(Err(5), |_| Ok::<_, i32>(1)),
852 /// Ok(1)
853 /// );
854 /// assert_eq!(
855 /// bind::<ResultWithOkBrand<i32>, _, _, _>(Ok(1), |x: i32| Err(x * 2)),
856 /// Ok(1)
857 /// );
858 /// ```
859 fn bind<'a, B: 'a, A: 'a, F>(
860 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
861 f: F,
862 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
863 where
864 F: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
865 {
866 match ma {
867 Ok(t) => Ok(t),
868 Err(e) => f(e),
869 }
870 }
871}
872
873impl<T: 'static> Foldable for ResultWithOkBrand<T> {
874 /// Folds the result from the right (over error).
875 ///
876 /// This method performs a right-associative fold of the result (over error).
877 ///
878 /// ### Type Signature
879 ///
880 /// `forall t b a. Foldable (Result t) => ((a, b) -> b, b, Result t a) -> b`
881 ///
882 /// ### Type Parameters
883 ///
884 /// * `FnBrand`: The brand of the cloneable function to use.
885 /// * `B`: The type of the accumulator.
886 /// * `A`: The type of the elements in the structure.
887 /// * `F`: The type of the folding function.
888 ///
889 /// ### Parameters
890 ///
891 /// * `func`: The folding function.
892 /// * `initial`: The initial value.
893 /// * `fa`: The result to fold.
894 ///
895 /// ### Returns
896 ///
897 /// `func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.
898 ///
899 /// ### Examples
900 ///
901 /// ```
902 /// use fp_library::functions::*;
903 /// use fp_library::brands::{ResultWithOkBrand, RcFnBrand};
904 ///
905 /// assert_eq!(fold_right::<RcFnBrand, ResultWithOkBrand<i32>, _, _, _>(|x: i32, acc| x + acc, 0, Err(1)), 1);
906 /// assert_eq!(fold_right::<RcFnBrand, ResultWithOkBrand<()>, _, _, _>(|x: i32, acc| x + acc, 0, Ok(())), 0);
907 /// ```
908 fn fold_right<'a, FnBrand, B: 'a, A: 'a, F>(
909 func: F,
910 initial: B,
911 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
912 ) -> B
913 where
914 F: Fn(A, B) -> B + 'a,
915 FnBrand: CloneableFn + 'a,
916 {
917 match fa {
918 Err(e) => func(e, initial),
919 Ok(_) => initial,
920 }
921 }
922
923 /// Folds the result from the left (over error).
924 ///
925 /// This method performs a left-associative fold of the result (over error).
926 ///
927 /// ### Type Signature
928 ///
929 /// `forall t b a. Foldable (Result t) => ((b, a) -> b, b, Result t a) -> b`
930 ///
931 /// ### Type Parameters
932 ///
933 /// * `FnBrand`: The brand of the cloneable function to use.
934 /// * `B`: The type of the accumulator.
935 /// * `A`: The type of the elements in the structure.
936 /// * `F`: The type of the folding function.
937 ///
938 /// ### Parameters
939 ///
940 /// * `func`: The folding function.
941 /// * `initial`: The initial value.
942 /// * `fa`: The result to fold.
943 ///
944 /// ### Returns
945 ///
946 /// `func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.
947 ///
948 /// ### Examples
949 ///
950 /// ```
951 /// use fp_library::functions::*;
952 /// use fp_library::brands::{ResultWithOkBrand, RcFnBrand};
953 ///
954 /// assert_eq!(fold_left::<RcFnBrand, ResultWithOkBrand<()>, _, _, _>(|acc, x: i32| acc + x, 0, Err(5)), 5);
955 /// assert_eq!(fold_left::<RcFnBrand, ResultWithOkBrand<i32>, _, _, _>(|acc, x: i32| acc + x, 0, Ok(1)), 0);
956 /// ```
957 fn fold_left<'a, FnBrand, B: 'a, A: 'a, F>(
958 func: F,
959 initial: B,
960 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
961 ) -> B
962 where
963 F: Fn(B, A) -> B + 'a,
964 FnBrand: CloneableFn + 'a,
965 {
966 match fa {
967 Err(e) => func(initial, e),
968 Ok(_) => initial,
969 }
970 }
971
972 /// Maps the value to a monoid and returns it (over error).
973 ///
974 /// This method maps the element of the result to a monoid and then returns it (over error).
975 ///
976 /// ### Type Signature
977 ///
978 /// `forall t m a. (Foldable (Result t), Monoid m) => ((a) -> m, Result t a) -> m`
979 ///
980 /// ### Type Parameters
981 ///
982 /// * `FnBrand`: The brand of the cloneable function to use.
983 /// * `M`: The type of the monoid.
984 /// * `A`: The type of the elements in the structure.
985 /// * `Func`: The type of the mapping function.
986 ///
987 /// ### Parameters
988 ///
989 /// * `func`: The mapping function.
990 /// * `fa`: The result to fold.
991 ///
992 /// ### Returns
993 ///
994 /// `func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.
995 ///
996 /// ### Examples
997 ///
998 /// ```
999 /// use fp_library::{brands::*, functions::*};
1000 ///
1001 /// assert_eq!(
1002 /// fold_map::<RcFnBrand, ResultWithOkBrand<()>, _, _, _>(|x: i32| x.to_string(), Err(5)),
1003 /// "5".to_string()
1004 /// );
1005 /// assert_eq!(
1006 /// fold_map::<RcFnBrand, ResultWithOkBrand<i32>, _, _, _>(|x: i32| x.to_string(), Ok(1)),
1007 /// "".to_string()
1008 /// );
1009 /// ```
1010 fn fold_map<'a, FnBrand, M, A: 'a, Func>(
1011 func: Func,
1012 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1013 ) -> M
1014 where
1015 M: Monoid + 'a,
1016 Func: Fn(A) -> M + 'a,
1017 FnBrand: CloneableFn + 'a,
1018 {
1019 match fa {
1020 Err(e) => func(e),
1021 Ok(_) => M::empty(),
1022 }
1023 }
1024}
1025
1026impl<T: Clone + 'static> Traversable for ResultWithOkBrand<T> {
1027 /// Traverses the result with an applicative function (over error).
1028 ///
1029 /// This method maps the element of the result to a computation, evaluates it, and combines the result into an applicative context (over error).
1030 ///
1031 /// ### Type Signature
1032 ///
1033 /// `forall t f b a. (Traversable (Result t), Applicative f) => (a -> f b, Result t a) -> f (Result t b)`
1034 ///
1035 /// ### Type Parameters
1036 ///
1037 /// * `F`: The applicative context.
1038 /// * `B`: The type of the elements in the resulting traversable structure.
1039 /// * `A`: The type of the elements in the traversable structure.
1040 /// * `Func`: The type of the function to apply.
1041 ///
1042 /// ### Parameters
1043 ///
1044 /// * `func`: The function to apply.
1045 /// * `ta`: The result to traverse.
1046 ///
1047 /// ### Returns
1048 ///
1049 /// The result wrapped in the applicative context.
1050 ///
1051 /// ### Examples
1052 ///
1053 /// ```
1054 /// use fp_library::functions::*;
1055 /// use fp_library::brands::{ResultWithOkBrand, OptionBrand};
1056 ///
1057 /// assert_eq!(
1058 /// traverse::<ResultWithOkBrand<()>, OptionBrand, _, _, _>(|x| Some(x * 2), Err(5)),
1059 /// Some(Err(10))
1060 /// );
1061 /// assert_eq!(
1062 /// traverse::<ResultWithOkBrand<i32>, OptionBrand, _, _, _>(|x: i32| Some(x * 2), Ok(1)),
1063 /// Some(Ok(1))
1064 /// );
1065 /// assert_eq!(
1066 /// traverse::<ResultWithOkBrand<()>, OptionBrand, _, _, _>(|_| None::<i32>, Err(5)),
1067 /// None
1068 /// );
1069 /// ```
1070 fn traverse<'a, F: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
1071 func: Func,
1072 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1073 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
1074 where
1075 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1076 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1077 {
1078 match ta {
1079 Err(e) => F::map(|b| Err(b), func(e)),
1080 Ok(t) => F::pure(Ok(t)),
1081 }
1082 }
1083
1084 /// Sequences a result of applicative (over error).
1085 ///
1086 /// This method evaluates the computation inside the result and accumulates the result into an applicative context (over error).
1087 ///
1088 /// ### Type Signature
1089 ///
1090 /// `forall t f a. (Traversable (Result t), Applicative f) => (Result t (f a)) -> f (Result t a)`
1091 ///
1092 /// ### Type Parameters
1093 ///
1094 /// * `F`: The applicative context.
1095 /// * `A`: The type of the elements in the traversable structure.
1096 ///
1097 /// ### Parameters
1098 ///
1099 /// * `ta`: The result containing the applicative value.
1100 ///
1101 /// ### Returns
1102 ///
1103 /// The result wrapped in the applicative context.
1104 ///
1105 /// ### Examples
1106 ///
1107 /// ```
1108 /// use fp_library::functions::*;
1109 /// use fp_library::brands::{ResultWithOkBrand, OptionBrand};
1110 ///
1111 /// assert_eq!(
1112 /// sequence::<ResultWithOkBrand<()>, OptionBrand, _>(Err(Some(5))),
1113 /// Some(Err(5))
1114 /// );
1115 /// assert_eq!(
1116 /// sequence::<ResultWithOkBrand<i32>, OptionBrand, i32>(Ok::<_, Option<i32>>(1)),
1117 /// Some(Ok::<i32, i32>(1))
1118 /// );
1119 /// assert_eq!(
1120 /// sequence::<ResultWithOkBrand<()>, OptionBrand, _>(Err(None::<i32>)),
1121 /// None
1122 /// );
1123 /// ```
1124 fn sequence<'a, F: Applicative, A: 'a + Clone>(
1125 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
1126 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
1127 where
1128 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1129 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1130 {
1131 match ta {
1132 Err(fe) => F::map(|e| Err(e), fe),
1133 Ok(t) => F::pure(Ok(t)),
1134 }
1135 }
1136}
1137
1138impl<E: 'static, FnBrand: SendCloneableFn> ParFoldable<FnBrand> for ResultWithErrBrand<E> {
1139 /// Maps the value to a monoid and returns it, or returns empty, in parallel.
1140 ///
1141 /// This method maps the element of the result to a monoid and then returns it. The mapping operation may be executed in parallel.
1142 ///
1143 /// ### Type Signature
1144 ///
1145 /// `forall fn_brand e m a. (ParFoldable (Result e), Monoid m, Send m, Sync m) => (fn_brand a m, Result a e) -> m`
1146 ///
1147 /// ### Type Parameters
1148 ///
1149 /// * `FnBrand`: The brand of thread-safe function to use.
1150 /// * `M`: The monoid type (must be `Send + Sync`).
1151 /// * `A`: The element type (must be `Send + Sync`).
1152 ///
1153 /// ### Parameters
1154 ///
1155 /// * `func`: The thread-safe function to map each element to a monoid.
1156 /// * `fa`: The result to fold.
1157 ///
1158 /// ### Returns
1159 ///
1160 /// The combined monoid value.
1161 ///
1162 /// ### Examples
1163 ///
1164 /// ```
1165 /// use fp_library::{brands::*, classes::*, functions::*, types::*};
1166 ///
1167 /// let x: Result<i32, ()> = Ok(5);
1168 /// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1169 /// assert_eq!(par_fold_map::<ArcFnBrand, ResultWithErrBrand<()>, _, _>(f.clone(), x), "5".to_string());
1170 ///
1171 /// let x_err: Result<i32, i32> = Err(1);
1172 /// assert_eq!(par_fold_map::<ArcFnBrand, ResultWithErrBrand<i32>, _, _>(f, x_err), "".to_string());
1173 /// ```
1174 fn par_fold_map<'a, M, A>(
1175 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1176 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1177 ) -> M
1178 where
1179 A: 'a + Clone + Send + Sync,
1180 M: Monoid + Send + Sync + 'a,
1181 {
1182 match fa {
1183 Ok(a) => func(a),
1184 Err(_) => M::empty(),
1185 }
1186 }
1187
1188 /// Folds the result from the right in parallel.
1189 ///
1190 /// This method folds the result by applying a function from right to left, potentially in parallel.
1191 ///
1192 /// ### Type Signature
1193 ///
1194 /// `forall fn_brand e b a. ParFoldable (Result e) => (fn_brand (a, b) b, b, Result a e) -> b`
1195 ///
1196 /// ### Type Parameters
1197 ///
1198 /// * `FnBrand`: The brand of thread-safe function to use.
1199 /// * `B`: The accumulator type (must be `Send + Sync`).
1200 /// * `A`: The element type (must be `Send + Sync`).
1201 ///
1202 /// ### Parameters
1203 ///
1204 /// * `func`: The thread-safe function to apply to each element and the accumulator.
1205 /// * `initial`: The initial value.
1206 /// * `fa`: The result to fold.
1207 ///
1208 /// ### Returns
1209 ///
1210 /// The final accumulator value.
1211 ///
1212 /// ### Examples
1213 ///
1214 /// ```
1215 /// use fp_library::{brands::*, classes::*, functions::*};
1216 ///
1217 /// let x: Result<i32, ()> = Ok(5);
1218 /// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1219 /// assert_eq!(par_fold_right::<ArcFnBrand, ResultWithErrBrand<()>, _, _>(f.clone(), 10, x), 15);
1220 ///
1221 /// let x_err: Result<i32, i32> = Err(1);
1222 /// assert_eq!(par_fold_right::<ArcFnBrand, ResultWithErrBrand<i32>, _, _>(f, 10, x_err), 10);
1223 /// ```
1224 fn par_fold_right<'a, B, A>(
1225 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1226 initial: B,
1227 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1228 ) -> B
1229 where
1230 A: 'a + Clone + Send + Sync,
1231 B: Send + Sync + 'a,
1232 {
1233 match fa {
1234 Ok(a) => func((a, initial)),
1235 Err(_) => initial,
1236 }
1237 }
1238}
1239
1240impl<T: 'static, FnBrand: SendCloneableFn> ParFoldable<FnBrand> for ResultWithOkBrand<T> {
1241 /// Maps the value to a monoid and returns it, or returns empty, in parallel (over error).
1242 ///
1243 /// This method maps the element of the result to a monoid and then returns it (over error). The mapping operation may be executed in parallel.
1244 ///
1245 /// ### Type Signature
1246 ///
1247 /// `forall fn_brand t m a. (ParFoldable (Result t), Monoid m, Send m, Sync m) => (fn_brand a m, Result t a) -> m`
1248 ///
1249 /// ### Type Parameters
1250 ///
1251 /// * `FnBrand`: The brand of thread-safe function to use.
1252 /// * `M`: The monoid type (must be `Send + Sync`).
1253 /// * `A`: The element type (must be `Send + Sync`).
1254 ///
1255 /// ### Parameters
1256 ///
1257 /// * `func`: The thread-safe function to map each element to a monoid.
1258 /// * `fa`: The result to fold.
1259 ///
1260 /// ### Returns
1261 ///
1262 /// The combined monoid value.
1263 ///
1264 /// ### Examples
1265 ///
1266 /// ```
1267 /// use fp_library::{brands::*, classes::*, functions::*, types::*};
1268 ///
1269 /// let x: Result<(), i32> = Err(5);
1270 /// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1271 /// assert_eq!(par_fold_map::<ArcFnBrand, ResultWithOkBrand<()>, _, _>(f.clone(), x), "5".to_string());
1272 ///
1273 /// let x_ok: Result<i32, i32> = Ok(1);
1274 /// assert_eq!(par_fold_map::<ArcFnBrand, ResultWithOkBrand<i32>, _, _>(f, x_ok), "".to_string());
1275 /// ```
1276 fn par_fold_map<'a, M, A>(
1277 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1278 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1279 ) -> M
1280 where
1281 A: 'a + Clone + Send + Sync,
1282 M: Monoid + Send + Sync + 'a,
1283 {
1284 match fa {
1285 Err(e) => func(e),
1286 Ok(_) => M::empty(),
1287 }
1288 }
1289
1290 /// Folds the result from the right in parallel (over error).
1291 ///
1292 /// This method folds the result by applying a function from right to left, potentially in parallel (over error).
1293 ///
1294 /// ### Type Signature
1295 ///
1296 /// `forall fn_brand t b a. ParFoldable (Result t) => (fn_brand (a, b) b, b, Result t a) -> b`
1297 ///
1298 /// ### Type Parameters
1299 ///
1300 /// * `FnBrand`: The brand of thread-safe function to use.
1301 /// * `B`: The accumulator type (must be `Send + Sync`).
1302 /// * `A`: The element type (must be `Send + Sync`).
1303 ///
1304 /// ### Parameters
1305 ///
1306 /// * `func`: The thread-safe function to apply to each element and the accumulator.
1307 /// * `initial`: The initial value.
1308 /// * `fa`: The result to fold.
1309 ///
1310 /// ### Returns
1311 ///
1312 /// The final accumulator value.
1313 ///
1314 /// ### Examples
1315 ///
1316 /// ```
1317 /// use fp_library::{brands::*, classes::*, functions::*};
1318 ///
1319 /// let x: Result<(), i32> = Err(5);
1320 /// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1321 /// assert_eq!(par_fold_right::<ArcFnBrand, ResultWithOkBrand<()>, _, _>(f.clone(), 10, x), 15);
1322 ///
1323 /// let x_ok: Result<i32, i32> = Ok(1);
1324 /// assert_eq!(par_fold_right::<ArcFnBrand, ResultWithOkBrand<i32>, _, _>(f, 10, x_ok), 10);
1325 /// ```
1326 fn par_fold_right<'a, B, A>(
1327 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1328 initial: B,
1329 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1330 ) -> B
1331 where
1332 A: 'a + Clone + Send + Sync,
1333 B: Send + Sync + 'a,
1334 {
1335 match fa {
1336 Err(e) => func((e, initial)),
1337 Ok(_) => initial,
1338 }
1339 }
1340}
1341
1342#[cfg(test)]
1343mod tests {
1344 use super::*;
1345 use crate::{brands::*, classes::bifunctor::*, functions::*};
1346 use quickcheck_macros::quickcheck;
1347
1348 // Bifunctor Tests
1349
1350 /// Tests `bimap` on `Ok` and `Err`.
1351 #[test]
1352 fn test_bimap() {
1353 let x: Result<i32, i32> = Ok(5);
1354 assert_eq!(bimap::<ResultBrand, _, _, _, _, _, _>(|e| e + 1, |s| s * 2, x), Ok(10));
1355
1356 let y: Result<i32, i32> = Err(5);
1357 assert_eq!(bimap::<ResultBrand, _, _, _, _, _, _>(|e| e + 1, |s| s * 2, y), Err(6));
1358 }
1359
1360 // Bifunctor Laws
1361
1362 /// Tests the identity law for Bifunctor.
1363 #[quickcheck]
1364 fn bifunctor_identity(x: Result<i32, i32>) -> bool {
1365 bimap::<ResultBrand, _, _, _, _, _, _>(identity, identity, x) == x
1366 }
1367
1368 /// Tests the composition law for Bifunctor.
1369 #[quickcheck]
1370 fn bifunctor_composition(x: Result<i32, i32>) -> bool {
1371 let f = |x: i32| x.wrapping_add(1);
1372 let g = |x: i32| x.wrapping_mul(2);
1373 let h = |x: i32| x.wrapping_sub(1);
1374 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1375
1376 bimap::<ResultBrand, _, _, _, _, _, _>(compose(f, g), compose(h, i), x)
1377 == bimap::<ResultBrand, _, _, _, _, _, _>(
1378 f,
1379 h,
1380 bimap::<ResultBrand, _, _, _, _, _, _>(g, i, x),
1381 )
1382 }
1383
1384 // Functor Laws
1385
1386 /// Tests the identity law for Functor.
1387 #[quickcheck]
1388 fn functor_identity(x: Result<i32, i32>) -> bool {
1389 map::<ResultWithErrBrand<i32>, _, _, _>(identity, x) == x
1390 }
1391
1392 /// Tests the composition law for Functor.
1393 #[quickcheck]
1394 fn functor_composition(x: Result<i32, i32>) -> bool {
1395 let f = |x: i32| x.wrapping_add(1);
1396 let g = |x: i32| x.wrapping_mul(2);
1397 map::<ResultWithErrBrand<i32>, _, _, _>(compose(f, g), x)
1398 == map::<ResultWithErrBrand<i32>, _, _, _>(
1399 f,
1400 map::<ResultWithErrBrand<i32>, _, _, _>(g, x),
1401 )
1402 }
1403
1404 // Applicative Laws
1405
1406 /// Tests the identity law for Applicative.
1407 #[quickcheck]
1408 fn applicative_identity(v: Result<i32, i32>) -> bool {
1409 apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1410 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1411 v,
1412 ) == v
1413 }
1414
1415 /// Tests the homomorphism law for Applicative.
1416 #[quickcheck]
1417 fn applicative_homomorphism(x: i32) -> bool {
1418 let f = |x: i32| x.wrapping_mul(2);
1419 apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1420 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(f)),
1421 pure::<ResultWithErrBrand<i32>, _>(x),
1422 ) == pure::<ResultWithErrBrand<i32>, _>(f(x))
1423 }
1424
1425 /// Tests the composition law for Applicative.
1426 #[quickcheck]
1427 fn applicative_composition(
1428 w: Result<i32, i32>,
1429 u_is_ok: bool,
1430 v_is_ok: bool,
1431 ) -> bool {
1432 let v_fn = |x: i32| x.wrapping_mul(2);
1433 let u_fn = |x: i32| x.wrapping_add(1);
1434
1435 let v = if v_is_ok {
1436 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(v_fn))
1437 } else {
1438 Err(100)
1439 };
1440 let u = if u_is_ok {
1441 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(u_fn))
1442 } else {
1443 Err(200)
1444 };
1445
1446 // RHS: u <*> (v <*> w)
1447 let vw = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(v.clone(), w.clone());
1448 let rhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(u.clone(), vw);
1449
1450 // LHS: pure(compose) <*> u <*> v <*> w
1451 // equivalent to (u . v) <*> w
1452 let uv = match (u, v) {
1453 (Ok(uf), Ok(vf)) => {
1454 let composed = move |x| uf(vf(x));
1455 Ok(<RcFnBrand as CloneableFn>::new(composed))
1456 }
1457 (Err(e), _) => Err(e),
1458 (_, Err(e)) => Err(e),
1459 };
1460
1461 let lhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(uv, w);
1462
1463 lhs == rhs
1464 }
1465
1466 /// Tests the interchange law for Applicative.
1467 #[quickcheck]
1468 fn applicative_interchange(y: i32) -> bool {
1469 // u <*> pure y = pure ($ y) <*> u
1470 let f = |x: i32| x.wrapping_mul(2);
1471 let u = pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(f));
1472
1473 let lhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1474 u.clone(),
1475 pure::<ResultWithErrBrand<i32>, _>(y),
1476 );
1477
1478 let rhs_fn =
1479 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1480 let rhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1481 pure::<ResultWithErrBrand<i32>, _>(rhs_fn),
1482 u,
1483 );
1484
1485 lhs == rhs
1486 }
1487
1488 // Monad Laws
1489
1490 /// Tests the left identity law for Monad.
1491 #[quickcheck]
1492 fn monad_left_identity(a: i32) -> bool {
1493 let f = |x: i32| -> Result<i32, i32> { Err(x.wrapping_mul(2)) };
1494 bind::<ResultWithErrBrand<i32>, _, _, _>(pure::<ResultWithErrBrand<i32>, _>(a), f) == f(a)
1495 }
1496
1497 /// Tests the right identity law for Monad.
1498 #[quickcheck]
1499 fn monad_right_identity(m: Result<i32, i32>) -> bool {
1500 bind::<ResultWithErrBrand<i32>, _, _, _>(m, pure::<ResultWithErrBrand<i32>, _>) == m
1501 }
1502
1503 /// Tests the associativity law for Monad.
1504 #[quickcheck]
1505 fn monad_associativity(m: Result<i32, i32>) -> bool {
1506 let f = |x: i32| -> Result<i32, i32> { Err(x.wrapping_mul(2)) };
1507 let g = |x: i32| -> Result<i32, i32> { Err(x.wrapping_add(1)) };
1508 bind::<ResultWithErrBrand<i32>, _, _, _>(bind::<ResultWithErrBrand<i32>, _, _, _>(m, f), g)
1509 == bind::<ResultWithErrBrand<i32>, _, _, _>(m, |x| {
1510 bind::<ResultWithErrBrand<i32>, _, _, _>(f(x), g)
1511 })
1512 }
1513
1514 // Edge Cases
1515
1516 /// Tests `map` on `Err`.
1517 #[test]
1518 fn map_err() {
1519 assert_eq!(
1520 map::<ResultWithErrBrand<i32>, _, _, _>(|x: i32| x + 1, Err::<i32, i32>(1)),
1521 Err(1)
1522 );
1523 }
1524
1525 /// Tests `bind` on `Err`.
1526 #[test]
1527 fn bind_err() {
1528 assert_eq!(
1529 bind::<ResultWithErrBrand<i32>, _, _, _>(Err::<i32, i32>(1), |x: i32| Ok(x + 1)),
1530 Err(1)
1531 );
1532 }
1533
1534 /// Tests `bind` returning `Err`.
1535 #[test]
1536 fn bind_returning_err() {
1537 assert_eq!(bind::<ResultWithErrBrand<i32>, _, _, _>(Ok(1), |_| Err::<i32, i32>(2)), Err(2));
1538 }
1539
1540 /// Tests `fold_right` on `Err`.
1541 #[test]
1542 fn fold_right_err() {
1543 assert_eq!(
1544 crate::classes::foldable::fold_right::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(
1545 |x: i32, acc| x + acc,
1546 0,
1547 Err(1)
1548 ),
1549 0
1550 );
1551 }
1552
1553 /// Tests `fold_left` on `Err`.
1554 #[test]
1555 fn fold_left_err() {
1556 assert_eq!(
1557 crate::classes::foldable::fold_left::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(
1558 |acc, x: i32| acc + x,
1559 0,
1560 Err(1)
1561 ),
1562 0
1563 );
1564 }
1565
1566 /// Tests `traverse` on `Err`.
1567 #[test]
1568 fn traverse_err() {
1569 assert_eq!(
1570 crate::classes::traversable::traverse::<ResultWithErrBrand<i32>, OptionBrand, _, _, _>(
1571 |x: i32| Some(x + 1),
1572 Err(1)
1573 ),
1574 Some(Err(1))
1575 );
1576 }
1577
1578 /// Tests `traverse` returning `Err`.
1579 #[test]
1580 fn traverse_returning_err() {
1581 assert_eq!(
1582 crate::classes::traversable::traverse::<ResultWithErrBrand<i32>, OptionBrand, _, _, _>(
1583 |_: i32| None::<i32>,
1584 Ok(1)
1585 ),
1586 None
1587 );
1588 }
1589
1590 // ParFoldable Tests for ResultWithErrBrand
1591
1592 /// Tests `par_fold_map` on `Ok`.
1593 #[test]
1594 fn par_fold_map_ok() {
1595 let x: Result<i32, ()> = Ok(5);
1596 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1597 assert_eq!(par_fold_map::<ArcFnBrand, ResultWithErrBrand<()>, _, _>(f, x), "5".to_string());
1598 }
1599
1600 /// Tests `par_fold_map` on `Err`.
1601 #[test]
1602 fn par_fold_map_err_val() {
1603 let x: Result<i32, i32> = Err(5);
1604 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1605 assert_eq!(par_fold_map::<ArcFnBrand, ResultWithErrBrand<i32>, _, _>(f, x), "".to_string());
1606 }
1607
1608 /// Tests `par_fold_right` on `Ok`.
1609 #[test]
1610 fn par_fold_right_ok() {
1611 let x: Result<i32, ()> = Ok(5);
1612 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1613 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithErrBrand<()>, _, _>(f, 10, x), 15);
1614 }
1615
1616 /// Tests `par_fold_right` on `Err`.
1617 #[test]
1618 fn par_fold_right_err_val() {
1619 let x: Result<i32, i32> = Err(5);
1620 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1621 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithErrBrand<i32>, _, _>(f, 10, x), 10);
1622 }
1623
1624 // ParFoldable Tests for ResultWithOkBrand
1625
1626 /// Tests `par_fold_map` on `Err` (which holds the value for ResultWithOkBrand).
1627 #[test]
1628 fn par_fold_map_err_ok_brand() {
1629 let x: Result<(), i32> = Err(5);
1630 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1631 assert_eq!(
1632 par_fold_map::<ArcFnBrand, ResultWithOkBrand<()>, _, _>(f.clone(), x),
1633 "5".to_string()
1634 );
1635 }
1636
1637 /// Tests `par_fold_map` on `Ok` (which is empty for ResultWithOkBrand).
1638 #[test]
1639 fn par_fold_map_ok_ok_brand() {
1640 let x: Result<i32, i32> = Ok(5);
1641 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1642 assert_eq!(par_fold_map::<ArcFnBrand, ResultWithOkBrand<i32>, _, _>(f, x), "".to_string());
1643 }
1644
1645 /// Tests `par_fold_right` on `Err` (which holds the value for ResultWithOkBrand).
1646 #[test]
1647 fn par_fold_right_err_ok_brand() {
1648 let x: Result<(), i32> = Err(5);
1649 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1650 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithOkBrand<()>, _, _>(f.clone(), 10, x), 15);
1651 }
1652
1653 /// Tests `par_fold_right` on `Ok` (which is empty for ResultWithOkBrand).
1654 #[test]
1655 fn par_fold_right_ok_ok_brand() {
1656 let x: Result<i32, i32> = Ok(5);
1657 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1658 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithOkBrand<i32>, _, _>(f, 10, x), 10);
1659 }
1660}