1use crate::{
6 Apply,
7 brands::{PairBrand, PairWithFirstBrand, PairWithSecondBrand},
8 classes::{
9 Applicative, ApplyFirst, ApplySecond, Bifunctor, CloneableFn, Foldable, Functor, Lift,
10 Monoid, ParFoldable, Pointed, Semiapplicative, Semigroup, Semimonad, SendCloneableFn,
11 Traversable,
12 },
13 impl_kind,
14 kinds::*,
15};
16use fp_macros::{doc_params, doc_type_params, hm_signature};
17
18#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
42pub struct Pair<First, Second>(pub First, pub Second);
43
44impl_kind! {
45 for PairBrand {
46 type Of<A, B> = Pair<A, B>;
47 }
48}
49
50impl_kind! {
51 for PairBrand {
52 type Of<'a, A: 'a, B: 'a>: 'a = Pair<A, B>;
53 }
54}
55
56impl Bifunctor for PairBrand {
57 #[hm_signature(Bifunctor)]
64 #[doc_type_params(
68 "The lifetime of the values.",
69 "The type of the first value.",
70 "The type of the mapped first value.",
71 "The type of the second value.",
72 "The type of the mapped second value.",
73 "The type of the function to apply to the first value.",
74 "The type of the function to apply to the second value."
75 )]
76 #[doc_params(
80 "The function to apply to the first value.",
81 "The function to apply to the second value.",
82 "The pair to map over."
83 )]
84 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a, F, G>(
98 f: F,
99 g: G,
100 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
101 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>)
102 where
103 F: Fn(A) -> B + 'a,
104 G: Fn(C) -> D + 'a,
105 {
106 let Pair(a, c) = p;
107 Pair(f(a), g(c))
108 }
109}
110
111impl_kind! {
114 impl<First: 'static> for PairWithFirstBrand<First> {
115 type Of<'a, A: 'a>: 'a = Pair<First, A>;
116 }
117}
118
119impl<First: 'static> Functor for PairWithFirstBrand<First> {
120 #[hm_signature(Functor)]
127 #[doc_type_params(
131 "The lifetime of the values.",
132 "The type of the second value.",
133 "The type of the result of applying the function.",
134 "The type of the function to apply."
135 )]
136 #[doc_params("The function to apply to the second value.", "The pair to map over.")]
140 fn map<'a, A: 'a, B: 'a, Func>(
153 func: Func,
154 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
155 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
156 where
157 Func: Fn(A) -> B + 'a,
158 {
159 Pair(fa.0, func(fa.1))
160 }
161}
162
163impl<First: Clone + 'static> Lift for PairWithFirstBrand<First>
164where
165 First: Semigroup,
166{
167 #[hm_signature(Lift)]
174 #[doc_type_params(
178 "The lifetime of the values.",
179 "The type of the first second value.",
180 "The type of the second second value.",
181 "The type of the result second value.",
182 "The type of the binary function."
183 )]
184 #[doc_params(
188 "The binary function to apply to the second values.",
189 "The first pair.",
190 "The second pair."
191 )]
192 fn lift2<'a, A, B, C, Func>(
208 func: Func,
209 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
210 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
211 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
212 where
213 Func: Fn(A, B) -> C + 'a,
214 A: Clone + 'a,
215 B: Clone + 'a,
216 C: 'a,
217 {
218 Pair(Semigroup::append(fa.0, fb.0), func(fa.1, fb.1))
219 }
220}
221
222impl<First: Clone + 'static> Pointed for PairWithFirstBrand<First>
223where
224 First: Monoid,
225{
226 #[hm_signature(Pointed)]
233 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
237 #[doc_params("The value to wrap.")]
241 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
254 Pair(Monoid::empty(), a)
255 }
256}
257
258impl<First: Clone + Semigroup + 'static> ApplyFirst for PairWithFirstBrand<First> {}
259impl<First: Clone + Semigroup + 'static> ApplySecond for PairWithFirstBrand<First> {}
260
261impl<First: Clone + 'static> Semiapplicative for PairWithFirstBrand<First>
262where
263 First: Semigroup,
264{
265 #[hm_signature(Semiapplicative)]
272 #[doc_type_params(
276 "The lifetime of the values.",
277 "The brand of the cloneable function wrapper.",
278 "The type of the input value.",
279 "The type of the output value."
280 )]
281 #[doc_params("The pair containing the function.", "The pair containing the value.")]
285 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
299 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
300 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
301 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
302 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
303 }
304}
305
306impl<First: Clone + 'static> Semimonad for PairWithFirstBrand<First>
307where
308 First: Semigroup,
309{
310 #[hm_signature(Semimonad)]
317 #[doc_type_params(
321 "The lifetime of the values.",
322 "The type of the result of the first computation.",
323 "The type of the result of the second computation.",
324 "The type of the function to apply."
325 )]
326 #[doc_params("The first pair.", "The function to apply to the second value.")]
330 fn bind<'a, A: 'a, B: 'a, Func>(
346 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
347 func: Func,
348 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
349 where
350 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
351 {
352 let Pair(first, second) = ma;
353 let Pair(next_first, next_second) = func(second);
354 Pair(Semigroup::append(first, next_first), next_second)
355 }
356}
357
358impl<First: 'static> Foldable for PairWithFirstBrand<First> {
359 #[hm_signature(Foldable)]
366 #[doc_type_params(
370 "The lifetime of the values.",
371 "The brand of the cloneable function to use.",
372 "The type of the elements in the structure.",
373 "The type of the accumulator.",
374 "The type of the folding function."
375 )]
376 #[doc_params("The folding function.", "The initial value.", "The pair to fold.")]
380 fn fold_right<'a, FnBrand, A: 'a, B: 'a, Func>(
393 func: Func,
394 initial: B,
395 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
396 ) -> B
397 where
398 Func: Fn(A, B) -> B + 'a,
399 FnBrand: CloneableFn + 'a,
400 {
401 func(fa.1, initial)
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(
425 "The function to apply to the accumulator and each element.",
426 "The initial value of the accumulator.",
427 "The identity to fold."
428 )]
429 fn fold_left<'a, FnBrand, A: 'a, B: 'a, Func>(
442 func: Func,
443 initial: B,
444 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
445 ) -> B
446 where
447 Func: Fn(B, A) -> B + 'a,
448 FnBrand: CloneableFn + 'a,
449 {
450 func(initial, fa.1)
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 pair to fold.")]
474 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
490 func: Func,
491 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
492 ) -> M
493 where
494 M: Monoid + 'a,
495 Func: Fn(A) -> M + 'a,
496 FnBrand: CloneableFn + 'a,
497 {
498 func(fa.1)
499 }
500}
501
502impl<First: Clone + 'static> Traversable for PairWithFirstBrand<First> {
503 #[hm_signature(Traversable)]
510 #[doc_type_params(
514 "The lifetime of the values.",
515 "The type of the elements in the traversable structure.",
516 "The type of the elements in the resulting traversable structure.",
517 "The applicative context.",
518 "The type of the function to apply."
519 )]
520 #[doc_params(
524 "The function to apply to each element, returning a value in an applicative context.",
525 "The pair to traverse."
526 )]
527 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
543 func: Func,
544 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
545 ) -> 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>)>)
546 where
547 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
548 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
549 {
550 let Pair(first, second) = ta;
551 F::map(move |b| Pair(first.clone(), b), func(second))
552 }
553 #[hm_signature(Traversable)]
560 #[doc_type_params(
564 "The lifetime of the values.",
565 "The type of the elements in the traversable structure.",
566 "The applicative context."
567 )]
568 #[doc_params("The pair containing the applicative value.")]
572 fn sequence<'a, A: 'a + Clone, F: Applicative>(
588 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>)>)
589 ) -> 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>)>)
590 where
591 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
592 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
593 {
594 let Pair(first, second) = ta;
595 F::map(move |a| Pair(first.clone(), a), second)
596 }
597}
598
599impl<First: 'static> ParFoldable for PairWithFirstBrand<First> {
600 #[hm_signature(ParFoldable)]
607 #[doc_type_params(
611 "The lifetime of the values.",
612 "The brand of the cloneable function wrapper.",
613 "The element type.",
614 "The monoid type."
615 )]
616 #[doc_params("The thread-safe function to map each element to a monoid.", "The pair to fold.")]
620 fn par_fold_map<'a, FnBrand, A, M>(
638 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
639 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
640 ) -> M
641 where
642 FnBrand: 'a + SendCloneableFn,
643 A: 'a + Clone + Send + Sync,
644 M: Monoid + Send + Sync + 'a,
645 {
646 func(fa.1)
647 }
648
649 #[hm_signature(ParFoldable)]
656 #[doc_type_params(
660 "The lifetime of the values.",
661 "The brand of the cloneable function wrapper.",
662 "The element type.",
663 "The accumulator type."
664 )]
665 #[doc_params(
669 "The thread-safe function to apply to each element and the accumulator.",
670 "The initial value.",
671 "The pair to fold."
672 )]
673 fn par_fold_right<'a, FnBrand, A, B>(
688 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
689 initial: B,
690 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
691 ) -> B
692 where
693 FnBrand: 'a + SendCloneableFn,
694 A: 'a + Clone + Send + Sync,
695 B: Send + Sync + 'a,
696 {
697 func((fa.1, initial))
698 }
699}
700impl_kind! {
703 impl<Second: 'static> for PairWithSecondBrand<Second> {
704 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
705 }
706}
707
708impl<Second: 'static> Functor for PairWithSecondBrand<Second> {
709 #[hm_signature(Functor)]
716 #[doc_type_params(
720 "The lifetime of the values.",
721 "The type of the first value.",
722 "The type of the result of applying the function.",
723 "The type of the function to apply."
724 )]
725 #[doc_params("The function to apply to the first value.", "The pair to map over.")]
729 fn map<'a, A: 'a, B: 'a, Func>(
742 func: Func,
743 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
744 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
745 where
746 Func: Fn(A) -> B + 'a,
747 {
748 Pair(func(fa.0), fa.1)
749 }
750}
751
752impl<Second: Clone + 'static> Lift for PairWithSecondBrand<Second>
753where
754 Second: Semigroup,
755{
756 #[hm_signature(Lift)]
763 #[doc_type_params(
767 "The lifetime of the values.",
768 "The type of the first first value.",
769 "The type of the second first value.",
770 "The type of the result first value.",
771 "The type of the binary function."
772 )]
773 #[doc_params(
777 "The binary function to apply to the first values.",
778 "The first pair.",
779 "The second pair."
780 )]
781 fn lift2<'a, A, B, C, Func>(
797 func: Func,
798 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
799 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
800 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
801 where
802 Func: Fn(A, B) -> C + 'a,
803 A: Clone + 'a,
804 B: Clone + 'a,
805 C: 'a,
806 {
807 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
808 }
809}
810
811impl<Second: Clone + 'static> Pointed for PairWithSecondBrand<Second>
812where
813 Second: Monoid,
814{
815 #[hm_signature(Pointed)]
822 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
826 #[doc_params("The value to wrap.")]
830 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
843 Pair(a, Monoid::empty())
844 }
845}
846
847impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairWithSecondBrand<Second> {}
848impl<Second: Clone + Semigroup + 'static> ApplySecond for PairWithSecondBrand<Second> {}
849
850impl<Second: Clone + 'static> Semiapplicative for PairWithSecondBrand<Second>
851where
852 Second: Semigroup,
853{
854 #[hm_signature(Semiapplicative)]
861 #[doc_type_params(
865 "The lifetime of the values.",
866 "The brand of the cloneable function wrapper.",
867 "The type of the input value.",
868 "The type of the output value."
869 )]
870 #[doc_params(
874 "The pair containing the function (in Err).",
875 "The pair containing the value (in Err)."
876 )]
877 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
891 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
892 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
893 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
894 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
895 }
896}
897
898impl<Second: Clone + 'static> Semimonad for PairWithSecondBrand<Second>
899where
900 Second: Semigroup,
901{
902 #[hm_signature(Semimonad)]
909 #[doc_type_params(
913 "The lifetime of the values.",
914 "The type of the result of the first computation.",
915 "The type of the result of the second computation.",
916 "The type of the function to apply."
917 )]
918 #[doc_params("The first result.", "The function to apply to the error value.")]
922 fn bind<'a, A: 'a, B: 'a, Func>(
938 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
939 func: Func,
940 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
941 where
942 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
943 {
944 let Pair(first, second) = ma;
945 let Pair(next_first, next_second) = func(first);
946 Pair(next_first, Semigroup::append(second, next_second))
947 }
948}
949
950impl<Second: 'static> Foldable for PairWithSecondBrand<Second> {
951 #[hm_signature(Foldable)]
958 #[doc_type_params(
962 "The lifetime of the values.",
963 "The brand of the cloneable function to use.",
964 "The type of the elements in the structure.",
965 "The type of the accumulator.",
966 "The type of the folding function."
967 )]
968 #[doc_params("The folding function.", "The initial value.", "The result to fold.")]
972 fn fold_right<'a, FnBrand, A: 'a, B: 'a, F>(
985 func: F,
986 initial: B,
987 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
988 ) -> B
989 where
990 F: Fn(A, B) -> B + 'a,
991 FnBrand: CloneableFn + 'a,
992 {
993 func(fa.0, initial)
994 }
995
996 #[hm_signature(Foldable)]
1003 #[doc_type_params(
1007 "The lifetime of the values.",
1008 "The brand of the cloneable function to use.",
1009 "The type of the elements in the structure.",
1010 "The type of the accumulator.",
1011 "The type of the folding function."
1012 )]
1013 #[doc_params("The folding function.", "The initial value.", "The result to fold.")]
1017 fn fold_left<'a, FnBrand, A: 'a, B: 'a, F>(
1030 func: F,
1031 initial: B,
1032 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1033 ) -> B
1034 where
1035 F: Fn(B, A) -> B + 'a,
1036 FnBrand: CloneableFn + 'a,
1037 {
1038 func(initial, fa.0)
1039 }
1040
1041 #[hm_signature(Foldable)]
1048 #[doc_type_params(
1052 "The lifetime of the values.",
1053 "The brand of the cloneable function to use.",
1054 "The type of the elements in the structure.",
1055 "The type of the monoid.",
1056 "The type of the mapping function."
1057 )]
1058 #[doc_params("The mapping function.", "The result to fold.")]
1062 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
1078 func: Func,
1079 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1080 ) -> M
1081 where
1082 M: Monoid + 'a,
1083 Func: Fn(A) -> M + 'a,
1084 FnBrand: CloneableFn + 'a,
1085 {
1086 func(fa.0)
1087 }
1088}
1089
1090impl<Second: Clone + 'static> Traversable for PairWithSecondBrand<Second> {
1091 #[hm_signature(Traversable)]
1098 #[doc_type_params(
1102 "The lifetime of the values.",
1103 "The type of the elements in the traversable structure.",
1104 "The type of the elements in the resulting traversable structure.",
1105 "The applicative context.",
1106 "The type of the function to apply."
1107 )]
1108 #[doc_params("The function to apply.", "The result to traverse.")]
1112 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
1128 func: Func,
1129 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1130 ) -> 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>)>)
1131 where
1132 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1133 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1134 {
1135 let Pair(first, second) = ta;
1136 F::map(move |b| Pair(b, second.clone()), func(first))
1137 }
1138
1139 #[hm_signature(Traversable)]
1146 #[doc_type_params(
1150 "The lifetime of the values.",
1151 "The type of the elements in the traversable structure.",
1152 "The applicative context."
1153 )]
1154 #[doc_params("The result containing the applicative value.")]
1158 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1174 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>)>)
1175 ) -> 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>)>)
1176 where
1177 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1178 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1179 {
1180 let Pair(first, second) = ta;
1181 F::map(move |a| Pair(a, second.clone()), first)
1182 }
1183}
1184
1185impl<Second: 'static> ParFoldable for PairWithSecondBrand<Second> {
1186 #[hm_signature(ParFoldable)]
1193 #[doc_type_params(
1197 "The lifetime of the values.",
1198 "The brand of the cloneable function wrapper.",
1199 "The element type.",
1200 "The monoid type."
1201 )]
1202 #[doc_params("The thread-safe function to map each element to a monoid.", "The pair to fold.")]
1206 fn par_fold_map<'a, FnBrand, A, M>(
1224 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1225 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1226 ) -> M
1227 where
1228 FnBrand: 'a + SendCloneableFn,
1229 A: 'a + Clone + Send + Sync,
1230 M: Monoid + Send + Sync + 'a,
1231 {
1232 func(fa.0)
1233 }
1234
1235 #[hm_signature(ParFoldable)]
1242 #[doc_type_params(
1246 "The lifetime of the values.",
1247 "The brand of the cloneable function wrapper.",
1248 "The element type.",
1249 "The accumulator type."
1250 )]
1251 #[doc_params(
1255 "The thread-safe function to apply to each element and the accumulator.",
1256 "The initial value.",
1257 "The pair to fold."
1258 )]
1259 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 func((fa.0, initial))
1284 }
1285}
1286
1287#[cfg(test)]
1288mod tests {
1289 use super::*;
1290 use crate::{brands::*, classes::bifunctor::*, functions::*};
1291 use quickcheck_macros::quickcheck;
1292
1293 #[test]
1297 fn test_bimap() {
1298 let x = Pair(1, 5);
1299 assert_eq!(bimap::<PairBrand, _, _, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1300 }
1301
1302 #[quickcheck]
1306 fn bifunctor_identity(
1307 first: String,
1308 second: i32,
1309 ) -> bool {
1310 let x = Pair(first, second);
1311 bimap::<PairBrand, _, _, _, _, _, _>(identity, identity, x.clone()) == x
1312 }
1313
1314 #[quickcheck]
1316 fn bifunctor_composition(
1317 first: i32,
1318 second: i32,
1319 ) -> bool {
1320 let x = Pair(first, second);
1321 let f = |x: i32| x.wrapping_add(1);
1322 let g = |x: i32| x.wrapping_mul(2);
1323 let h = |x: i32| x.wrapping_sub(1);
1324 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1325
1326 bimap::<PairBrand, _, _, _, _, _, _>(compose(f, g), compose(h, i), x.clone())
1327 == bimap::<PairBrand, _, _, _, _, _, _>(
1328 f,
1329 h,
1330 bimap::<PairBrand, _, _, _, _, _, _>(g, i, x),
1331 )
1332 }
1333
1334 #[quickcheck]
1338 fn functor_identity(
1339 first: String,
1340 second: i32,
1341 ) -> bool {
1342 let x = Pair(first, second);
1343 map::<PairWithFirstBrand<String>, _, _, _>(identity, x.clone()) == x
1344 }
1345
1346 #[quickcheck]
1348 fn functor_composition(
1349 first: String,
1350 second: i32,
1351 ) -> bool {
1352 let x = Pair(first, second);
1353 let f = |x: i32| x.wrapping_add(1);
1354 let g = |x: i32| x.wrapping_mul(2);
1355 map::<PairWithFirstBrand<String>, _, _, _>(compose(f, g), x.clone())
1356 == map::<PairWithFirstBrand<String>, _, _, _>(
1357 f,
1358 map::<PairWithFirstBrand<String>, _, _, _>(g, x),
1359 )
1360 }
1361
1362 #[quickcheck]
1366 fn applicative_identity(
1367 first: String,
1368 second: i32,
1369 ) -> bool {
1370 let v = Pair(first, second);
1371 apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1372 pure::<PairWithFirstBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1373 v.clone(),
1374 ) == v
1375 }
1376
1377 #[quickcheck]
1379 fn applicative_homomorphism(x: i32) -> bool {
1380 let f = |x: i32| x.wrapping_mul(2);
1381 apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1382 pure::<PairWithFirstBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1383 pure::<PairWithFirstBrand<String>, _>(x),
1384 ) == pure::<PairWithFirstBrand<String>, _>(f(x))
1385 }
1386
1387 #[quickcheck]
1389 fn applicative_composition(
1390 w_first: String,
1391 w_second: i32,
1392 u_seed: i32,
1393 v_seed: i32,
1394 ) -> bool {
1395 let w = Pair(w_first, w_second);
1396
1397 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1398 let u = pure::<PairWithFirstBrand<String>, _>(u_fn);
1399
1400 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1401 let v = pure::<PairWithFirstBrand<String>, _>(v_fn);
1402
1403 let vw = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(v.clone(), w.clone());
1405 let rhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(u.clone(), vw);
1406
1407 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1409 let f = f.clone();
1410 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1411 let f = f.clone();
1412 let g = g.clone();
1413 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1414 })
1415 });
1416
1417 let pure_compose = pure::<PairWithFirstBrand<String>, _>(compose_fn);
1418 let u_applied = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(pure_compose, u);
1419 let uv = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(u_applied, v);
1420 let lhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(uv, w);
1421
1422 lhs == rhs
1423 }
1424
1425 #[quickcheck]
1427 fn applicative_interchange(
1428 y: i32,
1429 u_seed: i32,
1430 ) -> bool {
1431 let f = move |x: i32| x.wrapping_mul(u_seed);
1433 let u = pure::<PairWithFirstBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1434
1435 let lhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1436 u.clone(),
1437 pure::<PairWithFirstBrand<String>, _>(y),
1438 );
1439
1440 let rhs_fn =
1441 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1442 let rhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1443 pure::<PairWithFirstBrand<String>, _>(rhs_fn),
1444 u,
1445 );
1446
1447 lhs == rhs
1448 }
1449
1450 #[quickcheck]
1454 fn monad_left_identity(a: i32) -> bool {
1455 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1456 bind::<PairWithFirstBrand<String>, _, _, _>(pure::<PairWithFirstBrand<String>, _>(a), f)
1457 == f(a)
1458 }
1459
1460 #[quickcheck]
1462 fn monad_right_identity(
1463 first: String,
1464 second: i32,
1465 ) -> bool {
1466 let m = Pair(first, second);
1467 bind::<PairWithFirstBrand<String>, _, _, _>(
1468 m.clone(),
1469 pure::<PairWithFirstBrand<String>, _>,
1470 ) == m
1471 }
1472
1473 #[quickcheck]
1475 fn monad_associativity(
1476 first: String,
1477 second: i32,
1478 ) -> bool {
1479 let m = Pair(first, second);
1480 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1481 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1482 bind::<PairWithFirstBrand<String>, _, _, _>(
1483 bind::<PairWithFirstBrand<String>, _, _, _>(m.clone(), f),
1484 g,
1485 ) == bind::<PairWithFirstBrand<String>, _, _, _>(m, |x| {
1486 bind::<PairWithFirstBrand<String>, _, _, _>(f(x), g)
1487 })
1488 }
1489
1490 #[test]
1494 fn par_fold_map_pair_with_first() {
1495 let x = Pair("a".to_string(), 1);
1496 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1497 assert_eq!(
1498 par_fold_map::<ArcFnBrand, PairWithFirstBrand<String>, _, _>(f, x),
1499 "1".to_string()
1500 );
1501 }
1502
1503 #[test]
1505 fn par_fold_right_pair_with_first() {
1506 let x = Pair("a".to_string(), 1);
1507 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1508 assert_eq!(par_fold_right::<ArcFnBrand, PairWithFirstBrand<String>, _, _>(f, 10, x), 11);
1509 }
1510
1511 #[test]
1515 fn par_fold_map_pair_with_second() {
1516 let x = Pair(1, "a".to_string());
1517 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1518 assert_eq!(
1519 par_fold_map::<ArcFnBrand, PairWithSecondBrand<String>, _, _>(f, x),
1520 "1".to_string()
1521 );
1522 }
1523
1524 #[test]
1526 fn par_fold_right_pair_with_second() {
1527 let x = Pair(1, "a".to_string());
1528 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1529 assert_eq!(par_fold_right::<ArcFnBrand, PairWithSecondBrand<String>, _, _>(f, 10, x), 11);
1530 }
1531}