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