1use crate::{
6 Apply,
7 brands::{ResultBrand, ResultWithErrBrand, ResultWithOkBrand},
8 classes::{
9 Applicative, ApplyFirst, ApplySecond, Bifunctor, CloneableFn, Foldable, Functor, Lift,
10 Monoid, ParFoldable, Pointed, Semiapplicative, Semimonad, SendCloneableFn, Traversable,
11 },
12 impl_kind,
13 kinds::*,
14};
15use fp_macros::{doc_params, doc_type_params, hm_signature};
16
17impl_kind! {
18 for ResultBrand {
19 type Of<A, B> = Result<B, A>;
20 }
21}
22
23impl_kind! {
24 for ResultBrand {
25 type Of<'a, A: 'a, B: 'a>: 'a = Result<B, A>;
26 }
27}
28
29impl Bifunctor for ResultBrand {
30 #[hm_signature(Bifunctor)]
37 #[doc_type_params(
41 "The lifetime of the values.",
42 "The type of the error value.",
43 "The type of the mapped error value.",
44 "The type of the success value.",
45 "The type of the mapped success value.",
46 "The type of the function to apply to the error.",
47 "The type of the function to apply to the success."
48 )]
49 #[doc_params(
53 "The function to apply to the error.",
54 "The function to apply to the success.",
55 "The result to map over."
56 )]
57 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a, F, G>(
74 f: F,
75 g: G,
76 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
77 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>)
78 where
79 F: Fn(A) -> B + 'a,
80 G: Fn(C) -> D + 'a,
81 {
82 match p {
83 Ok(c) => Ok(g(c)),
84 Err(a) => Err(f(a)),
85 }
86 }
87}
88
89impl_kind! {
92 impl<E: 'static> for ResultWithErrBrand<E> {
93 type Of<'a, A: 'a>: 'a = Result<A, E>;
94 }
95}
96
97impl<E: 'static> Functor for ResultWithErrBrand<E> {
98 #[hm_signature(Functor)]
105 #[doc_type_params(
109 "The lifetime of the values.",
110 "The type of the value inside the result.",
111 "The type of the result of applying the function.",
112 "The type of the function to apply."
113 )]
114 #[doc_params("The function to apply.", "The result to map over.")]
118 fn map<'a, A: 'a, B: 'a, Func>(
132 func: Func,
133 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
134 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
135 where
136 Func: Fn(A) -> B + 'a,
137 {
138 fa.map(func)
139 }
140}
141
142impl<E: Clone + 'static> Lift for ResultWithErrBrand<E> {
143 #[hm_signature(Lift)]
150 #[doc_type_params(
154 "The lifetime of the values.",
155 "The type of the first value.",
156 "The type of the second value.",
157 "The type of the result.",
158 "The type of the binary function."
159 )]
160 #[doc_params("The binary function to apply.", "The first result.", "The second result.")]
164 fn lift2<'a, A, B, C, Func>(
192 func: Func,
193 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
194 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
195 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
196 where
197 Func: Fn(A, B) -> C + 'a,
198 A: Clone + 'a,
199 B: Clone + 'a,
200 C: 'a,
201 {
202 match (fa, fb) {
203 (Ok(a), Ok(b)) => Ok(func(a, b)),
204 (Err(e), _) => Err(e),
205 (_, Err(e)) => Err(e),
206 }
207 }
208}
209
210impl<E: 'static> Pointed for ResultWithErrBrand<E> {
211 #[hm_signature(Pointed)]
218 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
222 #[doc_params("The value to wrap.")]
226 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
240 Ok(a)
241 }
242}
243
244impl<E: Clone + 'static> ApplyFirst for ResultWithErrBrand<E> {}
245impl<E: Clone + 'static> ApplySecond for ResultWithErrBrand<E> {}
246
247impl<E: Clone + 'static> Semiapplicative for ResultWithErrBrand<E> {
248 #[hm_signature(Semiapplicative)]
255 #[doc_type_params(
259 "The lifetime of the values.",
260 "The brand of the cloneable function wrapper.",
261 "The type of the input value.",
262 "The type of the output value."
263 )]
264 #[doc_params("The result containing the function.", "The result containing the value.")]
268 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
287 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
288 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
289 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
290 match (ff, fa) {
291 (Ok(f), Ok(a)) => Ok(f(a)),
292 (Err(e), _) => Err(e),
293 (_, Err(e)) => Err(e),
294 }
295 }
296}
297
298impl<E: Clone + 'static> Semimonad for ResultWithErrBrand<E> {
299 #[hm_signature(Semimonad)]
306 #[doc_type_params(
310 "The lifetime of the values.",
311 "The type of the result of the first computation.",
312 "The type of the result of the second computation.",
313 "The type of the function to apply."
314 )]
315 #[doc_params("The first result.", "The function to apply to the value inside the result.")]
319 fn bind<'a, A: 'a, B: 'a, Func>(
344 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
345 func: Func,
346 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
347 where
348 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
349 {
350 ma.and_then(func)
351 }
352}
353
354impl<E: 'static> Foldable for ResultWithErrBrand<E> {
355 #[hm_signature(Foldable)]
362 #[doc_type_params(
366 "The lifetime of the values.",
367 "The brand of the cloneable function to use.",
368 "The type of the elements in the structure.",
369 "The type of the accumulator.",
370 "The type of the folding function."
371 )]
372 #[doc_params("The folding function.", "The initial value.", "The result to fold.")]
376 fn fold_right<'a, FnBrand, A: 'a, B: 'a, F>(
390 func: F,
391 initial: B,
392 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
393 ) -> B
394 where
395 F: Fn(A, B) -> B + 'a,
396 FnBrand: CloneableFn + 'a,
397 {
398 match fa {
399 Ok(a) => func(a, initial),
400 Err(_) => initial,
401 }
402 }
403
404 #[hm_signature(Foldable)]
411 #[doc_type_params(
415 "The lifetime of the values.",
416 "The brand of the cloneable function to use.",
417 "The type of the elements in the structure.",
418 "The type of the accumulator.",
419 "The type of the folding function."
420 )]
421 #[doc_params("The folding function.", "The initial value.", "The result to fold.")]
425 fn fold_left<'a, FnBrand, A: 'a, B: 'a, F>(
439 func: F,
440 initial: B,
441 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
442 ) -> B
443 where
444 F: Fn(B, A) -> B + 'a,
445 FnBrand: CloneableFn + 'a,
446 {
447 match fa {
448 Ok(a) => func(initial, a),
449 Err(_) => initial,
450 }
451 }
452
453 #[hm_signature(Foldable)]
460 #[doc_type_params(
464 "The lifetime of the values.",
465 "The brand of the cloneable function to use.",
466 "The type of the elements in the structure.",
467 "The type of the monoid.",
468 "The type of the mapping function."
469 )]
470 #[doc_params("The mapping function.", "The result to fold.")]
474 fn fold_map<'a, FnBrand, A: 'a, M, F>(
494 func: F,
495 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
496 ) -> M
497 where
498 M: Monoid + 'a,
499 F: Fn(A) -> M + 'a,
500 FnBrand: CloneableFn + 'a,
501 {
502 match fa {
503 Ok(a) => func(a),
504 Err(_) => M::empty(),
505 }
506 }
507}
508
509impl<E: Clone + 'static> Traversable for ResultWithErrBrand<E> {
510 #[hm_signature(Traversable)]
517 #[doc_type_params(
521 "The lifetime of the values.",
522 "The type of the elements in the traversable structure.",
523 "The type of the elements in the resulting traversable structure.",
524 "The applicative context.",
525 "The type of the function to apply."
526 )]
527 #[doc_params("The function to apply.", "The result to traverse.")]
531 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
556 func: Func,
557 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
558 ) -> 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>)>)
559 where
560 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
561 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
562 {
563 match ta {
564 Ok(a) => F::map(|b| Ok(b), func(a)),
565 Err(e) => F::pure(Err(e)),
566 }
567 }
568
569 #[hm_signature(Traversable)]
576 #[doc_type_params(
580 "The lifetime of the values.",
581 "The type of the elements in the traversable structure.",
582 "The applicative context."
583 )]
584 #[doc_params("The result containing the applicative value.")]
588 fn sequence<'a, A: 'a + Clone, F: Applicative>(
613 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>)>)
614 ) -> 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>)>)
615 where
616 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
617 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
618 {
619 match ta {
620 Ok(fa) => F::map(|a| Ok(a), fa),
621 Err(e) => F::pure(Err(e)),
622 }
623 }
624}
625
626impl_kind! {
629 impl<T: 'static> for ResultWithOkBrand<T> {
630 type Of<'a, A: 'a>: 'a = Result<T, A>;
631 }
632}
633
634impl<T: 'static> Functor for ResultWithOkBrand<T> {
635 #[hm_signature(Functor)]
642 #[doc_type_params(
646 "The lifetime of the values.",
647 "The type of the error value inside the result.",
648 "The type of the result of applying the function.",
649 "The type of the function to apply."
650 )]
651 #[doc_params("The function to apply to the error.", "The result to map over.")]
655 fn map<'a, A: 'a, B: 'a, Func>(
669 func: Func,
670 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
671 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
672 where
673 Func: Fn(A) -> B + 'a,
674 {
675 match fa {
676 Ok(t) => Ok(t),
677 Err(e) => Err(func(e)),
678 }
679 }
680}
681
682impl<T: Clone + 'static> Lift for ResultWithOkBrand<T> {
683 #[hm_signature(Lift)]
690 #[doc_type_params(
694 "The lifetime of the values.",
695 "The type of the first error value.",
696 "The type of the second error value.",
697 "The type of the result error value.",
698 "The type of the binary function."
699 )]
700 #[doc_params(
704 "The binary function to apply to the errors.",
705 "The first result.",
706 "The second result."
707 )]
708 fn lift2<'a, A, B, C, Func>(
736 func: Func,
737 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
738 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
739 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
740 where
741 Func: Fn(A, B) -> C + 'a,
742 A: Clone + 'a,
743 B: Clone + 'a,
744 C: 'a,
745 {
746 match (fa, fb) {
747 (Err(a), Err(b)) => Err(func(a, b)),
748 (Ok(t), _) => Ok(t),
749 (_, Ok(t)) => Ok(t),
750 }
751 }
752}
753
754impl<T: 'static> Pointed for ResultWithOkBrand<T> {
755 #[hm_signature(Pointed)]
762 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
766 #[doc_params("The value to wrap.")]
770 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
784 Err(a)
785 }
786}
787
788impl<T: Clone + 'static> ApplyFirst for ResultWithOkBrand<T> {}
789impl<T: Clone + 'static> ApplySecond for ResultWithOkBrand<T> {}
790
791impl<T: Clone + 'static> Semiapplicative for ResultWithOkBrand<T> {
792 #[hm_signature(Semiapplicative)]
799 #[doc_type_params(
803 "The lifetime of the values.",
804 "The brand of the cloneable function wrapper.",
805 "The type of the input value.",
806 "The type of the output value."
807 )]
808 #[doc_params(
812 "The result containing the function (in Err).",
813 "The result containing the value (in Err)."
814 )]
815 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
834 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
835 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
836 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
837 match (ff, fa) {
838 (Err(f), Err(a)) => Err(f(a)),
839 (Ok(t), _) => Ok(t),
840 (_, Ok(t)) => Ok(t),
841 }
842 }
843}
844
845impl<T: Clone + 'static> Semimonad for ResultWithOkBrand<T> {
846 #[hm_signature(Semimonad)]
853 #[doc_type_params(
857 "The lifetime of the values.",
858 "The type of the result of the first computation.",
859 "The type of the result of the second computation.",
860 "The type of the function to apply."
861 )]
862 #[doc_params("The first result.", "The function to apply to the error value.")]
866 fn bind<'a, A: 'a, B: 'a, Func>(
891 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
892 func: Func,
893 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
894 where
895 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
896 {
897 match ma {
898 Ok(t) => Ok(t),
899 Err(e) => func(e),
900 }
901 }
902}
903
904impl<T: 'static> Foldable for ResultWithOkBrand<T> {
905 #[hm_signature(Foldable)]
912 #[doc_type_params(
916 "The lifetime of the values.",
917 "The brand of the cloneable function to use.",
918 "The type of the elements in the structure.",
919 "The type of the accumulator.",
920 "The type of the folding function."
921 )]
922 #[doc_params("The folding function.", "The initial value.", "The result to fold.")]
926 fn fold_right<'a, FnBrand, A: 'a, B: 'a, F>(
940 func: F,
941 initial: B,
942 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
943 ) -> B
944 where
945 F: Fn(A, B) -> B + 'a,
946 FnBrand: CloneableFn + 'a,
947 {
948 match fa {
949 Err(e) => func(e, initial),
950 Ok(_) => initial,
951 }
952 }
953
954 #[hm_signature(Foldable)]
961 #[doc_type_params(
965 "The lifetime of the values.",
966 "The brand of the cloneable function to use.",
967 "The type of the elements in the structure.",
968 "The type of the accumulator.",
969 "The type of the folding function."
970 )]
971 #[doc_params("The folding function.", "The initial value.", "The result to fold.")]
975 fn fold_left<'a, FnBrand, A: 'a, B: 'a, F>(
989 func: F,
990 initial: B,
991 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
992 ) -> B
993 where
994 F: Fn(B, A) -> B + 'a,
995 FnBrand: CloneableFn + 'a,
996 {
997 match fa {
998 Err(e) => func(initial, e),
999 Ok(_) => initial,
1000 }
1001 }
1002
1003 #[hm_signature(Foldable)]
1010 #[doc_type_params(
1014 "The lifetime of the values.",
1015 "The brand of the cloneable function to use.",
1016 "The type of the elements in the structure.",
1017 "The type of the monoid.",
1018 "The type of the mapping function."
1019 )]
1020 #[doc_params("The mapping function.", "The result to fold.")]
1024 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
1044 func: Func,
1045 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1046 ) -> M
1047 where
1048 M: Monoid + 'a,
1049 Func: Fn(A) -> M + 'a,
1050 FnBrand: CloneableFn + 'a,
1051 {
1052 match fa {
1053 Err(e) => func(e),
1054 Ok(_) => M::empty(),
1055 }
1056 }
1057}
1058
1059impl<T: Clone + 'static> Traversable for ResultWithOkBrand<T> {
1060 #[hm_signature(Traversable)]
1067 #[doc_type_params(
1071 "The lifetime of the values.",
1072 "The type of the elements in the traversable structure.",
1073 "The type of the elements in the resulting traversable structure.",
1074 "The applicative context.",
1075 "The type of the function to apply."
1076 )]
1077 #[doc_params("The function to apply.", "The result to traverse.")]
1081 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
1106 func: Func,
1107 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1108 ) -> 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>)>)
1109 where
1110 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1111 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1112 {
1113 match ta {
1114 Err(e) => F::map(|b| Err(b), func(e)),
1115 Ok(t) => F::pure(Ok(t)),
1116 }
1117 }
1118
1119 #[hm_signature(Traversable)]
1126 #[doc_type_params(
1130 "The lifetime of the values.",
1131 "The type of the elements in the traversable structure.",
1132 "The applicative context."
1133 )]
1134 #[doc_params("The result containing the applicative value.")]
1138 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1163 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>)>)
1164 ) -> 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>)>)
1165 where
1166 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1167 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1168 {
1169 match ta {
1170 Err(fe) => F::map(|e| Err(e), fe),
1171 Ok(t) => F::pure(Ok(t)),
1172 }
1173 }
1174}
1175
1176impl<E: 'static> ParFoldable for ResultWithErrBrand<E> {
1177 #[hm_signature(ParFoldable)]
1184 #[doc_type_params(
1188 "The lifetime of the values.",
1189 "The brand of the cloneable function wrapper.",
1190 "The element type.",
1191 "The monoid type."
1192 )]
1193 #[doc_params(
1197 "The thread-safe function to map each element to a monoid.",
1198 "The result to fold."
1199 )]
1200 fn par_fold_map<'a, FnBrand, A, M>(
1218 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1219 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1220 ) -> M
1221 where
1222 FnBrand: 'a + SendCloneableFn,
1223 A: 'a + Clone + Send + Sync,
1224 M: Monoid + Send + Sync + 'a,
1225 {
1226 match fa {
1227 Ok(a) => func(a),
1228 Err(_) => M::empty(),
1229 }
1230 }
1231
1232 #[hm_signature(ParFoldable)]
1239 #[doc_type_params(
1243 "The lifetime of the values.",
1244 "The brand of the cloneable function wrapper.",
1245 "The element type.",
1246 "The accumulator type."
1247 )]
1248 #[doc_params(
1252 "The thread-safe function to apply to each element and the accumulator.",
1253 "The initial value.",
1254 "The result to fold."
1255 )]
1256 fn par_fold_right<'a, FnBrand, A, B>(
1274 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1275 initial: B,
1276 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1277 ) -> B
1278 where
1279 FnBrand: 'a + SendCloneableFn,
1280 A: 'a + Clone + Send + Sync,
1281 B: Send + Sync + 'a,
1282 {
1283 match fa {
1284 Ok(a) => func((a, initial)),
1285 Err(_) => initial,
1286 }
1287 }
1288}
1289
1290impl<T: 'static> ParFoldable for ResultWithOkBrand<T> {
1291 #[hm_signature(ParFoldable)]
1298 #[doc_type_params(
1302 "The lifetime of the values.",
1303 "The brand of the cloneable function wrapper.",
1304 "The element type.",
1305 "The monoid type."
1306 )]
1307 #[doc_params(
1311 "The thread-safe function to map each element to a monoid.",
1312 "The result to fold."
1313 )]
1314 fn par_fold_map<'a, FnBrand, A, M>(
1332 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1333 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1334 ) -> M
1335 where
1336 FnBrand: 'a + SendCloneableFn,
1337 A: 'a + Clone + Send + Sync,
1338 M: Monoid + Send + Sync + 'a,
1339 {
1340 match fa {
1341 Err(e) => func(e),
1342 Ok(_) => M::empty(),
1343 }
1344 }
1345
1346 #[hm_signature(ParFoldable)]
1353 #[doc_type_params(
1357 "The lifetime of the values.",
1358 "The brand of the cloneable function wrapper.",
1359 "The element type.",
1360 "The accumulator type."
1361 )]
1362 #[doc_params(
1366 "The thread-safe function to apply to each element and the accumulator.",
1367 "The initial value.",
1368 "The result to fold."
1369 )]
1370 fn par_fold_right<'a, FnBrand, A, B>(
1388 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1389 initial: B,
1390 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1391 ) -> B
1392 where
1393 FnBrand: 'a + SendCloneableFn,
1394 A: 'a + Clone + Send + Sync,
1395 B: Send + Sync + 'a,
1396 {
1397 match fa {
1398 Err(e) => func((e, initial)),
1399 Ok(_) => initial,
1400 }
1401 }
1402}
1403
1404#[cfg(test)]
1405mod tests {
1406 use super::*;
1407 use crate::{brands::*, classes::bifunctor::*, functions::*};
1408 use quickcheck_macros::quickcheck;
1409
1410 #[test]
1414 fn test_bimap() {
1415 let x: Result<i32, i32> = Ok(5);
1416 assert_eq!(bimap::<ResultBrand, _, _, _, _, _, _>(|e| e + 1, |s| s * 2, x), Ok(10));
1417
1418 let y: Result<i32, i32> = Err(5);
1419 assert_eq!(bimap::<ResultBrand, _, _, _, _, _, _>(|e| e + 1, |s| s * 2, y), Err(6));
1420 }
1421
1422 #[quickcheck]
1426 fn bifunctor_identity(x: Result<i32, i32>) -> bool {
1427 bimap::<ResultBrand, _, _, _, _, _, _>(identity, identity, x) == x
1428 }
1429
1430 #[quickcheck]
1432 fn bifunctor_composition(x: Result<i32, i32>) -> bool {
1433 let f = |x: i32| x.wrapping_add(1);
1434 let g = |x: i32| x.wrapping_mul(2);
1435 let h = |x: i32| x.wrapping_sub(1);
1436 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1437
1438 bimap::<ResultBrand, _, _, _, _, _, _>(compose(f, g), compose(h, i), x)
1439 == bimap::<ResultBrand, _, _, _, _, _, _>(
1440 f,
1441 h,
1442 bimap::<ResultBrand, _, _, _, _, _, _>(g, i, x),
1443 )
1444 }
1445
1446 #[quickcheck]
1450 fn functor_identity(x: Result<i32, i32>) -> bool {
1451 map::<ResultWithErrBrand<i32>, _, _, _>(identity, x) == x
1452 }
1453
1454 #[quickcheck]
1456 fn functor_composition(x: Result<i32, i32>) -> bool {
1457 let f = |x: i32| x.wrapping_add(1);
1458 let g = |x: i32| x.wrapping_mul(2);
1459 map::<ResultWithErrBrand<i32>, _, _, _>(compose(f, g), x)
1460 == map::<ResultWithErrBrand<i32>, _, _, _>(
1461 f,
1462 map::<ResultWithErrBrand<i32>, _, _, _>(g, x),
1463 )
1464 }
1465
1466 #[quickcheck]
1470 fn applicative_identity(v: Result<i32, i32>) -> bool {
1471 apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1472 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1473 v,
1474 ) == v
1475 }
1476
1477 #[quickcheck]
1479 fn applicative_homomorphism(x: i32) -> bool {
1480 let f = |x: i32| x.wrapping_mul(2);
1481 apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1482 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(f)),
1483 pure::<ResultWithErrBrand<i32>, _>(x),
1484 ) == pure::<ResultWithErrBrand<i32>, _>(f(x))
1485 }
1486
1487 #[quickcheck]
1489 fn applicative_composition(
1490 w: Result<i32, i32>,
1491 u_is_ok: bool,
1492 v_is_ok: bool,
1493 ) -> bool {
1494 let v_fn = |x: i32| x.wrapping_mul(2);
1495 let u_fn = |x: i32| x.wrapping_add(1);
1496
1497 let v = if v_is_ok {
1498 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(v_fn))
1499 } else {
1500 Err(100)
1501 };
1502 let u = if u_is_ok {
1503 pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(u_fn))
1504 } else {
1505 Err(200)
1506 };
1507
1508 let vw = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(v.clone(), w.clone());
1510 let rhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(u.clone(), vw);
1511
1512 let uv = match (u, v) {
1515 (Ok(uf), Ok(vf)) => {
1516 let composed = move |x| uf(vf(x));
1517 Ok(<RcFnBrand as CloneableFn>::new(composed))
1518 }
1519 (Err(e), _) => Err(e),
1520 (_, Err(e)) => Err(e),
1521 };
1522
1523 let lhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(uv, w);
1524
1525 lhs == rhs
1526 }
1527
1528 #[quickcheck]
1530 fn applicative_interchange(y: i32) -> bool {
1531 let f = |x: i32| x.wrapping_mul(2);
1533 let u = pure::<ResultWithErrBrand<i32>, _>(<RcFnBrand as CloneableFn>::new(f));
1534
1535 let lhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1536 u.clone(),
1537 pure::<ResultWithErrBrand<i32>, _>(y),
1538 );
1539
1540 let rhs_fn =
1541 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1542 let rhs = apply::<RcFnBrand, ResultWithErrBrand<i32>, _, _>(
1543 pure::<ResultWithErrBrand<i32>, _>(rhs_fn),
1544 u,
1545 );
1546
1547 lhs == rhs
1548 }
1549
1550 #[quickcheck]
1554 fn monad_left_identity(a: i32) -> bool {
1555 let f = |x: i32| -> Result<i32, i32> { Err(x.wrapping_mul(2)) };
1556 bind::<ResultWithErrBrand<i32>, _, _, _>(pure::<ResultWithErrBrand<i32>, _>(a), f) == f(a)
1557 }
1558
1559 #[quickcheck]
1561 fn monad_right_identity(m: Result<i32, i32>) -> bool {
1562 bind::<ResultWithErrBrand<i32>, _, _, _>(m, pure::<ResultWithErrBrand<i32>, _>) == m
1563 }
1564
1565 #[quickcheck]
1567 fn monad_associativity(m: Result<i32, i32>) -> bool {
1568 let f = |x: i32| -> Result<i32, i32> { Err(x.wrapping_mul(2)) };
1569 let g = |x: i32| -> Result<i32, i32> { Err(x.wrapping_add(1)) };
1570 bind::<ResultWithErrBrand<i32>, _, _, _>(bind::<ResultWithErrBrand<i32>, _, _, _>(m, f), g)
1571 == bind::<ResultWithErrBrand<i32>, _, _, _>(m, |x| {
1572 bind::<ResultWithErrBrand<i32>, _, _, _>(f(x), g)
1573 })
1574 }
1575
1576 #[test]
1580 fn map_err() {
1581 assert_eq!(
1582 map::<ResultWithErrBrand<i32>, _, _, _>(|x: i32| x + 1, Err::<i32, i32>(1)),
1583 Err(1)
1584 );
1585 }
1586
1587 #[test]
1589 fn bind_err() {
1590 assert_eq!(
1591 bind::<ResultWithErrBrand<i32>, _, _, _>(Err::<i32, i32>(1), |x: i32| Ok(x + 1)),
1592 Err(1)
1593 );
1594 }
1595
1596 #[test]
1598 fn bind_returning_err() {
1599 assert_eq!(bind::<ResultWithErrBrand<i32>, _, _, _>(Ok(1), |_| Err::<i32, i32>(2)), Err(2));
1600 }
1601
1602 #[test]
1604 fn fold_right_err() {
1605 assert_eq!(
1606 crate::classes::foldable::fold_right::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(
1607 |x: i32, acc| x + acc,
1608 0,
1609 Err(1)
1610 ),
1611 0
1612 );
1613 }
1614
1615 #[test]
1617 fn fold_left_err() {
1618 assert_eq!(
1619 crate::classes::foldable::fold_left::<RcFnBrand, ResultWithErrBrand<i32>, _, _, _>(
1620 |acc, x: i32| acc + x,
1621 0,
1622 Err(1)
1623 ),
1624 0
1625 );
1626 }
1627
1628 #[test]
1630 fn traverse_err() {
1631 assert_eq!(
1632 crate::classes::traversable::traverse::<ResultWithErrBrand<i32>, _, _, OptionBrand, _>(
1633 |x: i32| Some(x + 1),
1634 Err(1)
1635 ),
1636 Some(Err(1))
1637 );
1638 }
1639
1640 #[test]
1642 fn traverse_returning_err() {
1643 assert_eq!(
1644 crate::classes::traversable::traverse::<ResultWithErrBrand<i32>, _, _, OptionBrand, _>(
1645 |_: i32| None::<i32>,
1646 Ok(1)
1647 ),
1648 None
1649 );
1650 }
1651
1652 #[test]
1656 fn par_fold_map_ok() {
1657 let x: Result<i32, ()> = Ok(5);
1658 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1659 assert_eq!(par_fold_map::<ArcFnBrand, ResultWithErrBrand<()>, _, _>(f, x), "5".to_string());
1660 }
1661
1662 #[test]
1664 fn par_fold_map_err_val() {
1665 let x: Result<i32, i32> = Err(5);
1666 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1667 assert_eq!(par_fold_map::<ArcFnBrand, ResultWithErrBrand<i32>, _, _>(f, x), "".to_string());
1668 }
1669
1670 #[test]
1672 fn par_fold_right_ok() {
1673 let x: Result<i32, ()> = Ok(5);
1674 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1675 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithErrBrand<()>, _, _>(f, 10, x), 15);
1676 }
1677
1678 #[test]
1680 fn par_fold_right_err_val() {
1681 let x: Result<i32, i32> = Err(5);
1682 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1683 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithErrBrand<i32>, _, _>(f, 10, x), 10);
1684 }
1685
1686 #[test]
1690 fn par_fold_map_err_ok_brand() {
1691 let x: Result<(), i32> = Err(5);
1692 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1693 assert_eq!(
1694 par_fold_map::<ArcFnBrand, ResultWithOkBrand<()>, _, _>(f.clone(), x),
1695 "5".to_string()
1696 );
1697 }
1698
1699 #[test]
1701 fn par_fold_map_ok_ok_brand() {
1702 let x: Result<i32, i32> = Ok(5);
1703 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1704 assert_eq!(par_fold_map::<ArcFnBrand, ResultWithOkBrand<i32>, _, _>(f, x), "".to_string());
1705 }
1706
1707 #[test]
1709 fn par_fold_right_err_ok_brand() {
1710 let x: Result<(), i32> = Err(5);
1711 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1712 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithOkBrand<()>, _, _>(f.clone(), 10, x), 15);
1713 }
1714
1715 #[test]
1717 fn par_fold_right_ok_ok_brand() {
1718 let x: Result<i32, i32> = Ok(5);
1719 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1720 assert_eq!(par_fold_right::<ArcFnBrand, ResultWithOkBrand<i32>, _, _>(f, 10, x), 10);
1721 }
1722}