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