1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::{
11 ResultBrand,
12 ResultErrAppliedBrand,
13 ResultOkAppliedBrand,
14 },
15 classes::{
16 Applicative,
17 ApplyFirst,
18 ApplySecond,
19 Bifoldable,
20 Bifunctor,
21 Bitraversable,
22 CloneableFn,
23 Foldable,
24 Functor,
25 Lift,
26 Monoid,
27 Pointed,
28 Semiapplicative,
29 Semimonad,
30 Traversable,
31 },
32 impl_kind,
33 kinds::*,
34 },
35 fp_macros::*,
36 };
37
38 impl_kind! {
39 for ResultBrand {
46 type Of<A, B> = Result<B, A>;
47 }
48 }
49
50 impl_kind! {
51 for ResultBrand {
55 type Of<'a, A: 'a, B: 'a>: 'a = Result<B, A>;
56 }
57 }
58
59 impl Bifunctor for ResultBrand {
60 #[document_signature]
64 #[document_type_parameters(
66 "The lifetime of the values.",
67 "The type of the error value.",
68 "The type of the mapped error value.",
69 "The type of the success value.",
70 "The type of the mapped success value."
71 )]
72 #[document_parameters(
74 "The function to apply to the error.",
75 "The function to apply to the success.",
76 "The result to map over."
77 )]
78 #[document_returns("A new result containing the mapped values.")]
80 #[document_examples]
81 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
96 f: impl Fn(A) -> B + 'a,
97 g: impl Fn(C) -> D + 'a,
98 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
99 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
100 match p {
101 Ok(c) => Ok(g(c)),
102 Err(a) => Err(f(a)),
103 }
104 }
105 }
106
107 impl Bifoldable for ResultBrand {
108 #[document_signature]
112 #[document_type_parameters(
114 "The lifetime of the values.",
115 "The brand of the cloneable function to use.",
116 "The error type (first position).",
117 "The success type (second position).",
118 "The accumulator type."
119 )]
120 #[document_parameters(
122 "The step function applied to the error value.",
123 "The step function applied to the success value.",
124 "The initial accumulator.",
125 "The result to fold."
126 )]
127 #[document_returns("`f(a, z)` for `Err(a)`, or `g(b, z)` for `Ok(b)`.")]
129 #[document_examples]
130 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
157 f: impl Fn(A, C) -> C + 'a,
158 g: impl Fn(B, C) -> C + 'a,
159 z: C,
160 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
161 ) -> C {
162 match p {
163 Err(a) => f(a, z),
164 Ok(b) => g(b, z),
165 }
166 }
167
168 #[document_signature]
172 #[document_type_parameters(
174 "The lifetime of the values.",
175 "The brand of the cloneable function to use.",
176 "The error type (first position).",
177 "The success type (second position).",
178 "The accumulator type."
179 )]
180 #[document_parameters(
182 "The step function applied to the error value.",
183 "The step function applied to the success value.",
184 "The initial accumulator.",
185 "The result to fold."
186 )]
187 #[document_returns("`f(z, a)` for `Err(a)`, or `g(z, b)` for `Ok(b)`.")]
189 #[document_examples]
190 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
217 f: impl Fn(C, A) -> C + 'a,
218 g: impl Fn(C, B) -> C + 'a,
219 z: C,
220 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
221 ) -> C {
222 match p {
223 Err(a) => f(z, a),
224 Ok(b) => g(z, b),
225 }
226 }
227
228 #[document_signature]
232 #[document_type_parameters(
234 "The lifetime of the values.",
235 "The brand of the cloneable function to use.",
236 "The error type (first position).",
237 "The success type (second position).",
238 "The monoid type."
239 )]
240 #[document_parameters(
242 "The function mapping the error to the monoid.",
243 "The function mapping the success to the monoid.",
244 "The result to fold."
245 )]
246 #[document_returns("`f(a)` for `Err(a)`, or `g(b)` for `Ok(b)`.")]
248 #[document_examples]
249 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
274 f: impl Fn(A) -> M + 'a,
275 g: impl Fn(B) -> M + 'a,
276 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
277 ) -> M
278 where
279 M: Monoid + 'a, {
280 match p {
281 Err(a) => f(a),
282 Ok(b) => g(b),
283 }
284 }
285 }
286
287 impl Bitraversable for ResultBrand {
288 #[document_signature]
293 #[document_type_parameters(
295 "The lifetime of the values.",
296 "The error type (first position).",
297 "The success type (second position).",
298 "The output error type.",
299 "The output success type.",
300 "The applicative context."
301 )]
302 #[document_parameters(
304 "The function applied to the error value.",
305 "The function applied to the success value.",
306 "The result to traverse."
307 )]
308 #[document_returns(
310 "`f(a)` wrapped in context for `Err(a)`, or `g(b)` wrapped in context for `Ok(b)`."
311 )]
312 #[document_examples]
313 fn bi_traverse<
338 'a,
339 A: 'a + Clone,
340 B: 'a + Clone,
341 C: 'a + Clone,
342 D: 'a + Clone,
343 F: Applicative,
344 >(
345 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
346 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
347 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
348 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>)>)
349 {
350 match p {
351 Err(a) => F::map(|c| Err(c), f(a)),
352 Ok(b) => F::map(|d| Ok(d), g(b)),
353 }
354 }
355 }
356
357 impl_kind! {
360 #[document_type_parameters("The error type.")]
361 impl<E: 'static> for ResultErrAppliedBrand<E> {
362 type Of<'a, A: 'a>: 'a = Result<A, E>;
363 }
364 }
365
366 #[document_type_parameters("The error type.")]
367 impl<E: 'static> Functor for ResultErrAppliedBrand<E> {
368 #[document_signature]
372 #[document_type_parameters(
374 "The lifetime of the values.",
375 "The type of the value inside the result.",
376 "The type of the result of applying the function."
377 )]
378 #[document_parameters("The function to apply.", "The result to map over.")]
380 #[document_returns(
382 "A new result containing the result of applying the function, or the original error."
383 )]
384 #[document_examples]
386 fn map<'a, A: 'a, B: 'a>(
397 func: impl Fn(A) -> B + 'a,
398 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
399 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
400 fa.map(func)
401 }
402 }
403
404 #[document_type_parameters("The error type.")]
405 impl<E: Clone + 'static> Lift for ResultErrAppliedBrand<E> {
406 #[document_signature]
410 #[document_type_parameters(
412 "The lifetime of the values.",
413 "The type of the first value.",
414 "The type of the second value.",
415 "The type of the result."
416 )]
417 #[document_parameters(
419 "The binary function to apply.",
420 "The first result.",
421 "The second result."
422 )]
423 #[document_returns(
425 "`Ok(f(a, b))` if both results are `Ok`, otherwise the first error encountered."
426 )]
427 #[document_examples]
428 fn lift2<'a, A, B, C>(
453 func: impl Fn(A, B) -> C + 'a,
454 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
455 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
456 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
457 where
458 A: Clone + 'a,
459 B: Clone + 'a,
460 C: 'a, {
461 match (fa, fb) {
462 (Ok(a), Ok(b)) => Ok(func(a, b)),
463 (Err(e), _) => Err(e),
464 (_, Err(e)) => Err(e),
465 }
466 }
467 }
468
469 #[document_type_parameters("The error type.")]
470 impl<E: 'static> Pointed for ResultErrAppliedBrand<E> {
471 #[document_signature]
475 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
477 #[document_parameters("The value to wrap.")]
479 #[document_returns("`Ok(a)`.")]
481 #[document_examples]
483 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
493 Ok(a)
494 }
495 }
496
497 #[document_type_parameters("The error type.")]
498 impl<E: Clone + 'static> ApplyFirst for ResultErrAppliedBrand<E> {}
499
500 #[document_type_parameters("The error type.")]
501 impl<E: Clone + 'static> ApplySecond for ResultErrAppliedBrand<E> {}
502
503 #[document_type_parameters("The error type.")]
504 impl<E: Clone + 'static> Semiapplicative for ResultErrAppliedBrand<E> {
505 #[document_signature]
509 #[document_type_parameters(
511 "The lifetime of the values.",
512 "The brand of the cloneable function wrapper.",
513 "The type of the input value.",
514 "The type of the output value."
515 )]
516 #[document_parameters(
518 "The result containing the function.",
519 "The result containing the value."
520 )]
521 #[document_returns("`Ok(f(a))` if both are `Ok`, otherwise the first error encountered.")]
523 #[document_examples]
524 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
543 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
544 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
545 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
546 match (ff, fa) {
547 (Ok(f), Ok(a)) => Ok(f(a)),
548 (Err(e), _) => Err(e),
549 (_, Err(e)) => Err(e),
550 }
551 }
552 }
553
554 #[document_type_parameters("The error type.")]
555 impl<E: Clone + 'static> Semimonad for ResultErrAppliedBrand<E> {
556 #[document_signature]
560 #[document_type_parameters(
562 "The lifetime of the values.",
563 "The type of the result of the first computation.",
564 "The type of the result of the second computation."
565 )]
566 #[document_parameters(
568 "The first result.",
569 "The function to apply to the value inside the result."
570 )]
571 #[document_returns(
573 "The result of applying `f` to the value if `ma` is `Ok`, otherwise the original error."
574 )]
575 #[document_examples]
576 fn bind<'a, A: 'a, B: 'a>(
588 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
589 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
590 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
591 ma.and_then(func)
592 }
593 }
594
595 #[document_type_parameters("The error type.")]
596 impl<E: 'static> Foldable for ResultErrAppliedBrand<E> {
597 #[document_signature]
601 #[document_type_parameters(
603 "The lifetime of the values.",
604 "The brand of the cloneable function to use.",
605 "The type of the elements in the structure.",
606 "The type of the accumulator."
607 )]
608 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
610 #[document_returns("`func(a, initial)` if `fa` is `Ok(a)`, otherwise `initial`.")]
612 #[document_examples]
614 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
631 func: impl Fn(A, B) -> B + 'a,
632 initial: B,
633 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
634 ) -> B
635 where
636 FnBrand: CloneableFn + 'a, {
637 match fa {
638 Ok(a) => func(a, initial),
639 Err(_) => initial,
640 }
641 }
642
643 #[document_signature]
647 #[document_type_parameters(
649 "The lifetime of the values.",
650 "The brand of the cloneable function to use.",
651 "The type of the elements in the structure.",
652 "The type of the accumulator."
653 )]
654 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
656 #[document_returns("`func(initial, a)` if `fa` is `Ok(a)`, otherwise `initial`.")]
658 #[document_examples]
660 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
677 func: impl Fn(B, A) -> B + 'a,
678 initial: B,
679 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
680 ) -> B
681 where
682 FnBrand: CloneableFn + 'a, {
683 match fa {
684 Ok(a) => func(initial, a),
685 Err(_) => initial,
686 }
687 }
688
689 #[document_signature]
693 #[document_type_parameters(
695 "The lifetime of the values.",
696 "The brand of the cloneable function to use.",
697 "The type of the elements in the structure.",
698 "The type of the monoid."
699 )]
700 #[document_parameters("The mapping function.", "The result to fold.")]
702 #[document_returns("`func(a)` if `fa` is `Ok(a)`, otherwise `M::empty()`.")]
704 #[document_examples]
706 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
723 func: impl Fn(A) -> M + 'a,
724 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
725 ) -> M
726 where
727 M: Monoid + 'a,
728 FnBrand: CloneableFn + 'a, {
729 match fa {
730 Ok(a) => func(a),
731 Err(_) => M::empty(),
732 }
733 }
734 }
735
736 #[document_type_parameters("The error type.")]
737 impl<E: Clone + 'static> Traversable for ResultErrAppliedBrand<E> {
738 #[document_signature]
742 #[document_type_parameters(
744 "The lifetime of the values.",
745 "The type of the elements in the traversable structure.",
746 "The type of the elements in the resulting traversable structure.",
747 "The applicative context."
748 )]
749 #[document_parameters("The function to apply.", "The result to traverse.")]
751 #[document_returns("The result wrapped in the applicative context.")]
753 #[document_examples]
755 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
779 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
780 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
781 ) -> 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>)>)
782 where
783 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
784 match ta {
785 Ok(a) => F::map(|b| Ok(b), func(a)),
786 Err(e) => F::pure(Err(e)),
787 }
788 }
789
790 #[document_signature]
794 #[document_type_parameters(
796 "The lifetime of the values.",
797 "The type of the elements in the traversable structure.",
798 "The applicative context."
799 )]
800 #[document_parameters("The result containing the applicative value.")]
802 #[document_returns("The result wrapped in the applicative context.")]
804 #[document_examples]
806 fn sequence<'a, A: 'a + Clone, F: Applicative>(
824 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>)>)
825 ) -> 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>)>)
826 where
827 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
828 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
829 match ta {
830 Ok(fa) => F::map(|a| Ok(a), fa),
831 Err(e) => F::pure(Err(e)),
832 }
833 }
834 }
835
836 impl_kind! {
839 #[document_type_parameters("The success type.")]
840 impl<T: 'static> for ResultOkAppliedBrand<T> {
841 type Of<'a, A: 'a>: 'a = Result<T, A>;
842 }
843 }
844
845 #[document_type_parameters("The success type.")]
846 impl<T: 'static> Functor for ResultOkAppliedBrand<T> {
847 #[document_signature]
851 #[document_type_parameters(
853 "The lifetime of the values.",
854 "The type of the error value inside the result.",
855 "The type of the result of applying the function."
856 )]
857 #[document_parameters("The function to apply to the error.", "The result to map over.")]
859 #[document_returns(
861 "A new result containing the mapped error, or the original success value."
862 )]
863 #[document_examples]
865 fn map<'a, A: 'a, B: 'a>(
876 func: impl Fn(A) -> B + 'a,
877 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
878 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
879 match fa {
880 Ok(t) => Ok(t),
881 Err(e) => Err(func(e)),
882 }
883 }
884 }
885
886 #[document_type_parameters("The success type.")]
887 impl<T: Clone + 'static> Lift for ResultOkAppliedBrand<T> {
888 #[document_signature]
892 #[document_type_parameters(
894 "The lifetime of the values.",
895 "The type of the first error value.",
896 "The type of the second error value.",
897 "The type of the result error value."
898 )]
899 #[document_parameters(
901 "The binary function to apply to the errors.",
902 "The first result.",
903 "The second result."
904 )]
905 #[document_returns(
907 "`Err(f(a, b))` if both results are `Err`, otherwise the first success encountered."
908 )]
909 #[document_examples]
910 fn lift2<'a, A, B, C>(
935 func: impl Fn(A, B) -> C + 'a,
936 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
937 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
938 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
939 where
940 A: Clone + 'a,
941 B: Clone + 'a,
942 C: 'a, {
943 match (fa, fb) {
944 (Err(a), Err(b)) => Err(func(a, b)),
945 (Ok(t), _) => Ok(t),
946 (_, Ok(t)) => Ok(t),
947 }
948 }
949 }
950
951 #[document_type_parameters("The success type.")]
952 impl<T: 'static> Pointed for ResultOkAppliedBrand<T> {
953 #[document_signature]
957 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
959 #[document_parameters("The value to wrap.")]
961 #[document_returns("`Err(a)`.")]
963 #[document_examples]
965 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
975 Err(a)
976 }
977 }
978
979 #[document_type_parameters("The success type.")]
980 impl<T: Clone + 'static> ApplyFirst for ResultOkAppliedBrand<T> {}
981
982 #[document_type_parameters("The success type.")]
983 impl<T: Clone + 'static> ApplySecond for ResultOkAppliedBrand<T> {}
984
985 #[document_type_parameters("The success type.")]
986 impl<T: Clone + 'static> Semiapplicative for ResultOkAppliedBrand<T> {
987 #[document_signature]
991 #[document_type_parameters(
993 "The lifetime of the values.",
994 "The brand of the cloneable function wrapper.",
995 "The type of the input value.",
996 "The type of the output value."
997 )]
998 #[document_parameters(
1000 "The result containing the function (in Err).",
1001 "The result containing the value (in Err)."
1002 )]
1003 #[document_returns(
1005 "`Err(f(a))` if both are `Err`, otherwise the first success encountered."
1006 )]
1007 #[document_examples]
1008 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1027 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1028 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1029 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1030 match (ff, fa) {
1031 (Err(f), Err(a)) => Err(f(a)),
1032 (Ok(t), _) => Ok(t),
1033 (_, Ok(t)) => Ok(t),
1034 }
1035 }
1036 }
1037
1038 #[document_type_parameters("The success type.")]
1039 impl<T: Clone + 'static> Semimonad for ResultOkAppliedBrand<T> {
1040 #[document_signature]
1044 #[document_type_parameters(
1046 "The lifetime of the values.",
1047 "The type of the result of the first computation.",
1048 "The type of the result of the second computation."
1049 )]
1050 #[document_parameters("The first result.", "The function to apply to the error value.")]
1052 #[document_returns(
1054 "The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
1055 )]
1056 #[document_examples]
1058 fn bind<'a, A: 'a, B: 'a>(
1070 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1071 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1072 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1073 match ma {
1074 Ok(t) => Ok(t),
1075 Err(e) => func(e),
1076 }
1077 }
1078 }
1079
1080 #[document_type_parameters("The success type.")]
1081 impl<T: 'static> Foldable for ResultOkAppliedBrand<T> {
1082 #[document_signature]
1086 #[document_type_parameters(
1088 "The lifetime of the values.",
1089 "The brand of the cloneable function to use.",
1090 "The type of the elements in the structure.",
1091 "The type of the accumulator."
1092 )]
1093 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1095 #[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
1097 #[document_examples]
1099 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1116 func: impl Fn(A, B) -> B + 'a,
1117 initial: B,
1118 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1119 ) -> B
1120 where
1121 FnBrand: CloneableFn + 'a, {
1122 match fa {
1123 Err(e) => func(e, initial),
1124 Ok(_) => initial,
1125 }
1126 }
1127
1128 #[document_signature]
1132 #[document_type_parameters(
1134 "The lifetime of the values.",
1135 "The brand of the cloneable function to use.",
1136 "The type of the elements in the structure.",
1137 "The type of the accumulator."
1138 )]
1139 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1141 #[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
1143 #[document_examples]
1145 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1162 func: impl Fn(B, A) -> B + 'a,
1163 initial: B,
1164 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1165 ) -> B
1166 where
1167 FnBrand: CloneableFn + 'a, {
1168 match fa {
1169 Err(e) => func(initial, e),
1170 Ok(_) => initial,
1171 }
1172 }
1173
1174 #[document_signature]
1178 #[document_type_parameters(
1180 "The lifetime of the values.",
1181 "The brand of the cloneable function to use.",
1182 "The type of the elements in the structure.",
1183 "The type of the monoid."
1184 )]
1185 #[document_parameters("The mapping function.", "The result to fold.")]
1187 #[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
1189 #[document_examples]
1191 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1208 func: impl Fn(A) -> M + 'a,
1209 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1210 ) -> M
1211 where
1212 M: Monoid + 'a,
1213 FnBrand: CloneableFn + 'a, {
1214 match fa {
1215 Err(e) => func(e),
1216 Ok(_) => M::empty(),
1217 }
1218 }
1219 }
1220
1221 #[document_type_parameters("The success type.")]
1222 impl<T: Clone + 'static> Traversable for ResultOkAppliedBrand<T> {
1223 #[document_signature]
1227 #[document_type_parameters(
1229 "The lifetime of the values.",
1230 "The type of the elements in the traversable structure.",
1231 "The type of the elements in the resulting traversable structure.",
1232 "The applicative context."
1233 )]
1234 #[document_parameters("The function to apply.", "The result to traverse.")]
1236 #[document_returns("The result wrapped in the applicative context.")]
1238 #[document_examples]
1240 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1264 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1265 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1266 ) -> 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>)>)
1267 where
1268 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1269 match ta {
1270 Err(e) => F::map(|b| Err(b), func(e)),
1271 Ok(t) => F::pure(Ok(t)),
1272 }
1273 }
1274
1275 #[document_signature]
1279 #[document_type_parameters(
1281 "The lifetime of the values.",
1282 "The type of the elements in the traversable structure.",
1283 "The applicative context."
1284 )]
1285 #[document_parameters("The result containing the applicative value.")]
1287 #[document_returns("The result wrapped in the applicative context.")]
1289 #[document_examples]
1291 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1309 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>)>)
1310 ) -> 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>)>)
1311 where
1312 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1313 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1314 match ta {
1315 Err(fe) => F::map(|e| Err(e), fe),
1316 Ok(t) => F::pure(Ok(t)),
1317 }
1318 }
1319 }
1320}
1321
1322#[cfg(test)]
1323mod tests {
1324
1325 use {
1326 crate::{
1327 brands::*,
1328 classes::{
1329 CloneableFn,
1330 bifunctor::*,
1331 },
1332 functions::*,
1333 },
1334 quickcheck_macros::quickcheck,
1335 };
1336
1337 #[test]
1341 fn test_bimap() {
1342 let x: Result<i32, i32> = Ok(5);
1343 assert_eq!(bimap::<ResultBrand, _, _, _, _>(|e| e + 1, |s| s * 2, x), Ok(10));
1344
1345 let y: Result<i32, i32> = Err(5);
1346 assert_eq!(bimap::<ResultBrand, _, _, _, _>(|e| e + 1, |s| s * 2, y), Err(6));
1347 }
1348
1349 #[quickcheck]
1353 fn bifunctor_identity(x: Result<i32, i32>) -> bool {
1354 bimap::<ResultBrand, _, _, _, _>(identity, identity, x) == x
1355 }
1356
1357 #[quickcheck]
1359 fn bifunctor_composition(x: Result<i32, i32>) -> bool {
1360 let f = |x: i32| x.wrapping_add(1);
1361 let g = |x: i32| x.wrapping_mul(2);
1362 let h = |x: i32| x.wrapping_sub(1);
1363 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1364
1365 bimap::<ResultBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1366 == bimap::<ResultBrand, _, _, _, _>(f, h, bimap::<ResultBrand, _, _, _, _>(g, i, x))
1367 }
1368
1369 #[quickcheck]
1373 fn functor_identity(x: Result<i32, i32>) -> bool {
1374 map::<ResultErrAppliedBrand<i32>, _, _>(identity, x) == x
1375 }
1376
1377 #[quickcheck]
1379 fn functor_composition(x: Result<i32, i32>) -> bool {
1380 let f = |x: i32| x.wrapping_add(1);
1381 let g = |x: i32| x.wrapping_mul(2);
1382 map::<ResultErrAppliedBrand<i32>, _, _>(compose(f, g), x)
1383 == map::<ResultErrAppliedBrand<i32>, _, _>(
1384 f,
1385 map::<ResultErrAppliedBrand<i32>, _, _>(g, x),
1386 )
1387 }
1388
1389 #[quickcheck]
1393 fn applicative_identity(v: Result<i32, i32>) -> bool {
1394 apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(
1395 pure::<ResultErrAppliedBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1396 v,
1397 ) == v
1398 }
1399
1400 #[quickcheck]
1402 fn applicative_homomorphism(x: i32) -> bool {
1403 let f = |x: i32| x.wrapping_mul(2);
1404 apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(
1405 pure::<ResultErrAppliedBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(f)),
1406 pure::<ResultErrAppliedBrand<i32>, _>(x),
1407 ) == pure::<ResultErrAppliedBrand<i32>, _>(f(x))
1408 }
1409
1410 #[quickcheck]
1412 fn applicative_composition(
1413 w: Result<i32, i32>,
1414 u_is_ok: bool,
1415 v_is_ok: bool,
1416 ) -> bool {
1417 let v_fn = |x: i32| x.wrapping_mul(2);
1418 let u_fn = |x: i32| x.wrapping_add(1);
1419
1420 let v = if v_is_ok {
1421 pure::<ResultErrAppliedBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(v_fn))
1422 } else {
1423 Err(100)
1424 };
1425 let u = if u_is_ok {
1426 pure::<ResultErrAppliedBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(u_fn))
1427 } else {
1428 Err(200)
1429 };
1430
1431 let vw = apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(v.clone(), w);
1433 let rhs = apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(u.clone(), vw);
1434
1435 let uv = match (u, v) {
1438 (Ok(uf), Ok(vf)) => {
1439 let composed = move |x| uf(vf(x));
1440 Ok(<RcFnBrand as CloneableFn>::new(composed))
1441 }
1442 (Err(e), _) => Err(e),
1443 (_, Err(e)) => Err(e),
1444 };
1445
1446 let lhs = apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(uv, w);
1447
1448 lhs == rhs
1449 }
1450
1451 #[quickcheck]
1453 fn applicative_interchange(y: i32) -> bool {
1454 let f = |x: i32| x.wrapping_mul(2);
1456 let u = pure::<ResultErrAppliedBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(f));
1457
1458 let lhs = apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(
1459 u.clone(),
1460 pure::<ResultErrAppliedBrand<i32>, _>(y),
1461 );
1462
1463 let rhs_fn =
1464 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1465 let rhs = apply::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(
1466 pure::<ResultErrAppliedBrand<i32>, _>(rhs_fn),
1467 u,
1468 );
1469
1470 lhs == rhs
1471 }
1472
1473 #[quickcheck]
1477 fn monad_left_identity(a: i32) -> bool {
1478 let f = |x: i32| -> Result<i32, i32> { Err(x.wrapping_mul(2)) };
1479 bind::<ResultErrAppliedBrand<i32>, _, _>(pure::<ResultErrAppliedBrand<i32>, _>(a), f)
1480 == f(a)
1481 }
1482
1483 #[quickcheck]
1485 fn monad_right_identity(m: Result<i32, i32>) -> bool {
1486 bind::<ResultErrAppliedBrand<i32>, _, _>(m, pure::<ResultErrAppliedBrand<i32>, _>) == m
1487 }
1488
1489 #[quickcheck]
1491 fn monad_associativity(m: Result<i32, i32>) -> bool {
1492 let f = |x: i32| -> Result<i32, i32> { Err(x.wrapping_mul(2)) };
1493 let g = |x: i32| -> Result<i32, i32> { Err(x.wrapping_add(1)) };
1494 bind::<ResultErrAppliedBrand<i32>, _, _>(bind::<ResultErrAppliedBrand<i32>, _, _>(m, f), g)
1495 == bind::<ResultErrAppliedBrand<i32>, _, _>(m, |x| {
1496 bind::<ResultErrAppliedBrand<i32>, _, _>(f(x), g)
1497 })
1498 }
1499
1500 #[test]
1504 fn map_err() {
1505 assert_eq!(
1506 map::<ResultErrAppliedBrand<i32>, _, _>(|x: i32| x + 1, Err::<i32, i32>(1)),
1507 Err(1)
1508 );
1509 }
1510
1511 #[test]
1513 fn bind_err() {
1514 assert_eq!(
1515 bind::<ResultErrAppliedBrand<i32>, _, _>(Err::<i32, i32>(1), |x: i32| Ok(x + 1)),
1516 Err(1)
1517 );
1518 }
1519
1520 #[test]
1522 fn bind_returning_err() {
1523 assert_eq!(bind::<ResultErrAppliedBrand<i32>, _, _>(Ok(1), |_| Err::<i32, i32>(2)), Err(2));
1524 }
1525
1526 #[test]
1528 fn fold_right_err() {
1529 assert_eq!(
1530 crate::classes::foldable::fold_right::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(
1531 |x: i32, acc| x + acc,
1532 0,
1533 Err(1)
1534 ),
1535 0
1536 );
1537 }
1538
1539 #[test]
1541 fn fold_left_err() {
1542 assert_eq!(
1543 crate::classes::foldable::fold_left::<RcFnBrand, ResultErrAppliedBrand<i32>, _, _>(
1544 |acc, x: i32| acc + x,
1545 0,
1546 Err(1)
1547 ),
1548 0
1549 );
1550 }
1551
1552 #[test]
1554 fn traverse_err() {
1555 assert_eq!(
1556 crate::classes::traversable::traverse::<ResultErrAppliedBrand<i32>, _, _, OptionBrand>(
1557 |x: i32| Some(x + 1),
1558 Err(1)
1559 ),
1560 Some(Err(1))
1561 );
1562 }
1563
1564 #[test]
1566 fn traverse_returning_err() {
1567 assert_eq!(
1568 crate::classes::traversable::traverse::<ResultErrAppliedBrand<i32>, _, _, OptionBrand>(
1569 |_: i32| None::<i32>,
1570 Ok(1)
1571 ),
1572 None
1573 );
1574 }
1575}