1#[fp_macros::document_module]
6mod inner {
7 use crate::{
8 Apply,
9 brands::{PairBrand, PairWithFirstBrand, PairWithSecondBrand},
10 classes::{
11 Applicative, ApplyFirst, ApplySecond, Bifunctor, CloneableFn, Foldable, Functor, Lift,
12 Monoid, ParFoldable, Pointed, Semiapplicative, Semigroup, Semimonad, SendCloneableFn,
13 Traversable,
14 },
15 impl_kind,
16 kinds::*,
17 };
18 use fp_macros::{document_fields, document_parameters, document_type_parameters};
19
20 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
36 #[document_fields("The first value.", "The second value.")]
40 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
52 pub struct Pair<First, Second>(pub First, pub Second);
53
54 impl_kind! {
55 for PairBrand {
56 type Of<First,Second> = Pair<First, Second>;
57 }
58 }
59
60 impl_kind! {
61 for PairBrand {
62 type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
63 }
64 }
65
66 impl Bifunctor for PairBrand {
67 #[document_signature]
74 #[document_type_parameters(
78 "The lifetime of the values.",
79 "The type of the first value.",
80 "The type of the mapped first value.",
81 "The type of the second value.",
82 "The type of the mapped second value.",
83 "The type of the function to apply to the first value.",
84 "The type of the function to apply to the second value."
85 )]
86 #[document_parameters(
90 "The function to apply to the first value.",
91 "The function to apply to the second value.",
92 "The pair to map over."
93 )]
94 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a, F, G>(
108 f: F,
109 g: G,
110 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
111 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>)
112 where
113 F: Fn(A) -> B + 'a,
114 G: Fn(C) -> D + 'a,
115 {
116 let Pair(a, c) = p;
117 Pair(f(a), g(c))
118 }
119 }
120
121 impl_kind! {
124 #[document_type_parameters("The type of the first value in the pair.")]
127 impl<First: 'static> for PairWithFirstBrand<First> {
128 type Of<'a, A: 'a>: 'a = Pair<First, A>;
129 }
130 }
131
132 #[document_type_parameters("The type of the first value in the pair.")]
135 impl<First: 'static> Functor for PairWithFirstBrand<First> {
136 #[document_signature]
143 #[document_type_parameters(
147 "The lifetime of the values.",
148 "The type of the second value.",
149 "The type of the result of applying the function.",
150 "The type of the function to apply."
151 )]
152 #[document_parameters(
156 "The function to apply to the second value.",
157 "The pair to map over."
158 )]
159 fn map<'a, A: 'a, B: 'a, Func>(
172 func: Func,
173 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
174 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
175 where
176 Func: Fn(A) -> B + 'a,
177 {
178 Pair(fa.0, func(fa.1))
179 }
180 }
181
182 #[document_type_parameters("The type of the first value in the pair.")]
185 impl<First: Clone + 'static> Lift for PairWithFirstBrand<First>
186 where
187 First: Semigroup,
188 {
189 #[document_signature]
196 #[document_type_parameters(
200 "The lifetime of the values.",
201 "The type of the first second value.",
202 "The type of the second second value.",
203 "The type of the result second value.",
204 "The type of the binary function."
205 )]
206 #[document_parameters(
210 "The binary function to apply to the second values.",
211 "The first pair.",
212 "The second pair."
213 )]
214 fn lift2<'a, A, B, C, Func>(
230 func: Func,
231 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
232 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
233 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
234 where
235 Func: Fn(A, B) -> C + 'a,
236 A: Clone + 'a,
237 B: Clone + 'a,
238 C: 'a,
239 {
240 Pair(Semigroup::append(fa.0, fb.0), func(fa.1, fb.1))
241 }
242 }
243
244 #[document_type_parameters("The type of the first value in the pair.")]
247 impl<First: Clone + 'static> Pointed for PairWithFirstBrand<First>
248 where
249 First: Monoid,
250 {
251 #[document_signature]
258 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
262 #[document_parameters("The value to wrap.")]
266 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
279 Pair(Monoid::empty(), a)
280 }
281 }
282
283 #[document_type_parameters("The type of the first value in the pair.")]
286 impl<First: Clone + Semigroup + 'static> ApplyFirst for PairWithFirstBrand<First> {}
287
288 #[document_type_parameters("The type of the first value in the pair.")]
291 impl<First: Clone + Semigroup + 'static> ApplySecond for PairWithFirstBrand<First> {}
292
293 #[document_type_parameters("The type of the first value in the pair.")]
296 impl<First: Clone + 'static> Semiapplicative for PairWithFirstBrand<First>
297 where
298 First: Semigroup,
299 {
300 #[document_signature]
307 #[document_type_parameters(
311 "The lifetime of the values.",
312 "The brand of the cloneable function wrapper.",
313 "The type of the input value.",
314 "The type of the output value."
315 )]
316 #[document_parameters(
320 "The pair containing the function.",
321 "The pair containing the value."
322 )]
323 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
337 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
338 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
339 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
340 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
341 }
342 }
343
344 #[document_type_parameters("The type of the first value in the pair.")]
347 impl<First: Clone + 'static> Semimonad for PairWithFirstBrand<First>
348 where
349 First: Semigroup,
350 {
351 #[document_signature]
358 #[document_type_parameters(
362 "The lifetime of the values.",
363 "The type of the result of the first computation.",
364 "The type of the result of the second computation.",
365 "The type of the function to apply."
366 )]
367 #[document_parameters("The first pair.", "The function to apply to the second value.")]
371 fn bind<'a, A: 'a, B: 'a, Func>(
387 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
388 func: Func,
389 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
390 where
391 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
392 {
393 let Pair(first, second) = ma;
394 let Pair(next_first, next_second) = func(second);
395 Pair(Semigroup::append(first, next_first), next_second)
396 }
397 }
398
399 #[document_type_parameters("The type of the first value in the pair.")]
402 #[document_type_parameters("The type of the first value in the pair.")]
405 impl<First: 'static> Foldable for PairWithFirstBrand<First> {
406 #[document_signature]
413 #[document_type_parameters(
417 "The lifetime of the values.",
418 "The brand of the cloneable function to use.",
419 "The type of the elements in the structure.",
420 "The type of the accumulator.",
421 "The type of the folding function."
422 )]
423 #[document_parameters("The folding function.", "The initial value.", "The pair to fold.")]
427 fn fold_right<'a, FnBrand, A: 'a, B: 'a, Func>(
440 func: Func,
441 initial: B,
442 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
443 ) -> B
444 where
445 Func: Fn(A, B) -> B + 'a,
446 FnBrand: CloneableFn + 'a,
447 {
448 func(fa.1, initial)
449 }
450
451 #[document_signature]
458 #[document_type_parameters(
462 "The lifetime of the values.",
463 "The brand of the cloneable function to use.",
464 "The type of the elements in the structure.",
465 "The type of the accumulator.",
466 "The type of the folding function."
467 )]
468 #[document_parameters(
472 "The function to apply to the accumulator and each element.",
473 "The initial value of the accumulator.",
474 "The identity to fold."
475 )]
476 fn fold_left<'a, FnBrand, A: 'a, B: 'a, Func>(
489 func: Func,
490 initial: B,
491 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
492 ) -> B
493 where
494 Func: Fn(B, A) -> B + 'a,
495 FnBrand: CloneableFn + 'a,
496 {
497 func(initial, fa.1)
498 }
499
500 #[document_signature]
507 #[document_type_parameters(
511 "The lifetime of the values.",
512 "The brand of the cloneable function to use.",
513 "The type of the elements in the structure.",
514 "The type of the monoid.",
515 "The type of the mapping function."
516 )]
517 #[document_parameters("The mapping function.", "The pair to fold.")]
521 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
537 func: Func,
538 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
539 ) -> M
540 where
541 M: Monoid + 'a,
542 Func: Fn(A) -> M + 'a,
543 FnBrand: CloneableFn + 'a,
544 {
545 func(fa.1)
546 }
547 }
548
549 #[document_type_parameters("The type of the first value in the pair.")]
552 #[document_type_parameters("The type of the first value in the pair.")]
555 impl<First: Clone + 'static> Traversable for PairWithFirstBrand<First> {
556 #[document_signature]
563 #[document_type_parameters(
567 "The lifetime of the values.",
568 "The type of the elements in the traversable structure.",
569 "The type of the elements in the resulting traversable structure.",
570 "The applicative context.",
571 "The type of the function to apply."
572 )]
573 #[document_parameters(
577 "The function to apply to each element, returning a value in an applicative context.",
578 "The pair to traverse."
579 )]
580 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
596 func: Func,
597 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
598 ) -> 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>)>)
599 where
600 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
601 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
602 {
603 let Pair(first, second) = ta;
604 F::map(move |b| Pair(first.clone(), b), func(second))
605 }
606 #[document_signature]
613 #[document_type_parameters(
617 "The lifetime of the values.",
618 "The type of the elements in the traversable structure.",
619 "The applicative context."
620 )]
621 #[document_parameters("The pair containing the applicative value.")]
625 fn sequence<'a, A: 'a + Clone, F: Applicative>(
641 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>)>)
642 ) -> 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>)>)
643 where
644 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
645 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
646 {
647 let Pair(first, second) = ta;
648 F::map(move |a| Pair(first.clone(), a), second)
649 }
650 }
651
652 #[document_type_parameters("The type of the first value in the pair.")]
655 #[document_type_parameters("The type of the first value in the pair.")]
658 impl<First: 'static> ParFoldable for PairWithFirstBrand<First> {
659 #[document_signature]
666 #[document_type_parameters(
670 "The lifetime of the values.",
671 "The brand of the cloneable function wrapper.",
672 "The element type.",
673 "The monoid type."
674 )]
675 #[document_parameters(
679 "The thread-safe function to map each element to a monoid.",
680 "The pair to fold."
681 )]
682 fn par_fold_map<'a, FnBrand, A, M>(
700 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
701 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
702 ) -> M
703 where
704 FnBrand: 'a + SendCloneableFn,
705 A: 'a + Clone + Send + Sync,
706 M: Monoid + Send + Sync + 'a,
707 {
708 func(fa.1)
709 }
710
711 #[document_signature]
718 #[document_type_parameters(
722 "The lifetime of the values.",
723 "The brand of the cloneable function wrapper.",
724 "The element type.",
725 "The accumulator type."
726 )]
727 #[document_parameters(
731 "The thread-safe function to apply to each element and the accumulator.",
732 "The initial value.",
733 "The pair to fold."
734 )]
735 fn par_fold_right<'a, FnBrand, A, B>(
750 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
751 initial: B,
752 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
753 ) -> B
754 where
755 FnBrand: 'a + SendCloneableFn,
756 A: 'a + Clone + Send + Sync,
757 B: Send + Sync + 'a,
758 {
759 func((fa.1, initial))
760 }
761 }
762 impl_kind! {
765 #[document_type_parameters("The type of the second value in the pair.")]
768 impl<Second: 'static> for PairWithSecondBrand<Second> {
769 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
770 }
771 }
772
773 #[document_type_parameters("The type of the second value in the pair.")]
776 impl<Second: 'static> Functor for PairWithSecondBrand<Second> {
777 #[document_signature]
784 #[document_type_parameters(
788 "The lifetime of the values.",
789 "The type of the first value.",
790 "The type of the result of applying the function.",
791 "The type of the function to apply."
792 )]
793 #[document_parameters("The function to apply to the first value.", "The pair to map over.")]
797 fn map<'a, A: 'a, B: 'a, Func>(
810 func: Func,
811 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
812 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
813 where
814 Func: Fn(A) -> B + 'a,
815 {
816 Pair(func(fa.0), fa.1)
817 }
818 }
819
820 #[document_type_parameters("The type of the second value in the pair.")]
823 impl<Second: Clone + 'static> Lift for PairWithSecondBrand<Second>
824 where
825 Second: Semigroup,
826 {
827 #[document_signature]
834 #[document_type_parameters(
838 "The lifetime of the values.",
839 "The type of the first first value.",
840 "The type of the second first value.",
841 "The type of the result first value.",
842 "The type of the binary function."
843 )]
844 #[document_parameters(
848 "The binary function to apply to the first values.",
849 "The first pair.",
850 "The second pair."
851 )]
852 fn lift2<'a, A, B, C, Func>(
868 func: Func,
869 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
870 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
871 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
872 where
873 Func: Fn(A, B) -> C + 'a,
874 A: Clone + 'a,
875 B: Clone + 'a,
876 C: 'a,
877 {
878 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
879 }
880 }
881
882 #[document_type_parameters("The type of the second value in the pair.")]
885 impl<Second: Clone + 'static> Pointed for PairWithSecondBrand<Second>
886 where
887 Second: Monoid,
888 {
889 #[document_signature]
896 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
900 #[document_parameters("The value to wrap.")]
904 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
917 Pair(a, Monoid::empty())
918 }
919 }
920
921 #[document_type_parameters("The type of the second value in the pair.")]
924 impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairWithSecondBrand<Second> {}
925
926 #[document_type_parameters("The type of the second value in the pair.")]
929 impl<Second: Clone + Semigroup + 'static> ApplySecond for PairWithSecondBrand<Second> {}
930
931 #[document_type_parameters("The type of the second value in the pair.")]
934 impl<Second: Clone + 'static> Semiapplicative for PairWithSecondBrand<Second>
935 where
936 Second: Semigroup,
937 {
938 #[document_signature]
945 #[document_type_parameters(
949 "The lifetime of the values.",
950 "The brand of the cloneable function wrapper.",
951 "The type of the input value.",
952 "The type of the output value."
953 )]
954 #[document_parameters(
958 "The pair containing the function (in Err).",
959 "The pair containing the value (in Err)."
960 )]
961 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
975 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
976 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
977 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
978 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
979 }
980 }
981
982 #[document_type_parameters("The type of the second value in the pair.")]
985 impl<Second: Clone + 'static> Semimonad for PairWithSecondBrand<Second>
986 where
987 Second: Semigroup,
988 {
989 #[document_signature]
996 #[document_type_parameters(
1000 "The lifetime of the values.",
1001 "The type of the result of the first computation.",
1002 "The type of the result of the second computation.",
1003 "The type of the function to apply."
1004 )]
1005 #[document_parameters("The first result.", "The function to apply to the error value.")]
1009 fn bind<'a, A: 'a, B: 'a, Func>(
1025 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1026 func: Func,
1027 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
1028 where
1029 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1030 {
1031 let Pair(first, second) = ma;
1032 let Pair(next_first, next_second) = func(first);
1033 Pair(next_first, Semigroup::append(second, next_second))
1034 }
1035 }
1036
1037 #[document_type_parameters("The type of the second value in the pair.")]
1040 #[document_type_parameters("The type of the second value in the pair.")]
1043 impl<Second: 'static> Foldable for PairWithSecondBrand<Second> {
1044 #[document_signature]
1051 #[document_type_parameters(
1055 "The lifetime of the values.",
1056 "The brand of the cloneable function to use.",
1057 "The type of the elements in the structure.",
1058 "The type of the accumulator.",
1059 "The type of the folding function."
1060 )]
1061 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1065 fn fold_right<'a, FnBrand, A: 'a, B: 'a, F>(
1078 func: F,
1079 initial: B,
1080 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1081 ) -> B
1082 where
1083 F: Fn(A, B) -> B + 'a,
1084 FnBrand: CloneableFn + 'a,
1085 {
1086 func(fa.0, initial)
1087 }
1088
1089 #[document_signature]
1096 #[document_type_parameters(
1100 "The lifetime of the values.",
1101 "The brand of the cloneable function to use.",
1102 "The type of the elements in the structure.",
1103 "The type of the accumulator.",
1104 "The type of the folding function."
1105 )]
1106 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1110 fn fold_left<'a, FnBrand, A: 'a, B: 'a, F>(
1123 func: F,
1124 initial: B,
1125 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1126 ) -> B
1127 where
1128 F: Fn(B, A) -> B + 'a,
1129 FnBrand: CloneableFn + 'a,
1130 {
1131 func(initial, fa.0)
1132 }
1133
1134 #[document_signature]
1141 #[document_type_parameters(
1145 "The lifetime of the values.",
1146 "The brand of the cloneable function to use.",
1147 "The type of the elements in the structure.",
1148 "The type of the monoid.",
1149 "The type of the mapping function."
1150 )]
1151 #[document_parameters("The mapping function.", "The result to fold.")]
1155 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
1171 func: Func,
1172 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1173 ) -> M
1174 where
1175 M: Monoid + 'a,
1176 Func: Fn(A) -> M + 'a,
1177 FnBrand: CloneableFn + 'a,
1178 {
1179 func(fa.0)
1180 }
1181 }
1182
1183 #[document_type_parameters("The type of the second value in the pair.")]
1186 #[document_type_parameters("The type of the second value in the pair.")]
1189 impl<Second: Clone + 'static> Traversable for PairWithSecondBrand<Second> {
1190 #[document_signature]
1197 #[document_type_parameters(
1201 "The lifetime of the values.",
1202 "The type of the elements in the traversable structure.",
1203 "The type of the elements in the resulting traversable structure.",
1204 "The applicative context.",
1205 "The type of the function to apply."
1206 )]
1207 #[document_parameters("The function to apply.", "The result to traverse.")]
1211 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
1227 func: Func,
1228 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1229 ) -> 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>)>)
1230 where
1231 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1232 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1233 {
1234 let Pair(first, second) = ta;
1235 F::map(move |b| Pair(b, second.clone()), func(first))
1236 }
1237
1238 #[document_signature]
1245 #[document_type_parameters(
1249 "The lifetime of the values.",
1250 "The type of the elements in the traversable structure.",
1251 "The applicative context."
1252 )]
1253 #[document_parameters("The result containing the applicative value.")]
1257 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1273 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>)>)
1274 ) -> 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>)>)
1275 where
1276 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1277 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1278 {
1279 let Pair(first, second) = ta;
1280 F::map(move |a| Pair(a, second.clone()), first)
1281 }
1282 }
1283
1284 #[document_type_parameters("The type of the second value in the pair.")]
1287 #[document_type_parameters("The type of the second value in the pair.")]
1290 impl<Second: 'static> ParFoldable for PairWithSecondBrand<Second> {
1291 #[document_signature]
1298 #[document_type_parameters(
1302 "The lifetime of the values.",
1303 "The brand of the cloneable function wrapper.",
1304 "The element type.",
1305 "The monoid type."
1306 )]
1307 #[document_parameters(
1311 "The thread-safe function to map each element to a monoid.",
1312 "The pair 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 func(fa.0)
1341 }
1342
1343 #[document_signature]
1350 #[document_type_parameters(
1354 "The lifetime of the values.",
1355 "The brand of the cloneable function wrapper.",
1356 "The element type.",
1357 "The accumulator type."
1358 )]
1359 #[document_parameters(
1363 "The thread-safe function to apply to each element and the accumulator.",
1364 "The initial value.",
1365 "The pair to fold."
1366 )]
1367 fn par_fold_right<'a, FnBrand, A, B>(
1382 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1383 initial: B,
1384 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1385 ) -> B
1386 where
1387 FnBrand: 'a + SendCloneableFn,
1388 A: 'a + Clone + Send + Sync,
1389 B: Send + Sync + 'a,
1390 {
1391 func((fa.0, initial))
1392 }
1393 }
1394}
1395pub use inner::*;
1396
1397#[cfg(test)]
1398mod tests {
1399 use super::inner::*;
1400 use crate::{
1401 brands::*,
1402 classes::{CloneableFn, bifunctor::*},
1403 functions::*,
1404 };
1405 use quickcheck_macros::quickcheck;
1406
1407 #[test]
1411 fn test_bimap() {
1412 let x = Pair(1, 5);
1413 assert_eq!(bimap::<PairBrand, _, _, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1414 }
1415
1416 #[quickcheck]
1420 fn bifunctor_identity(
1421 first: String,
1422 second: i32,
1423 ) -> bool {
1424 let x = Pair(first, second);
1425 bimap::<PairBrand, _, _, _, _, _, _>(identity, identity, x.clone()) == x
1426 }
1427
1428 #[quickcheck]
1430 fn bifunctor_composition(
1431 first: i32,
1432 second: i32,
1433 ) -> bool {
1434 let x = Pair(first, second);
1435 let f = |x: i32| x.wrapping_add(1);
1436 let g = |x: i32| x.wrapping_mul(2);
1437 let h = |x: i32| x.wrapping_sub(1);
1438 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1439
1440 bimap::<PairBrand, _, _, _, _, _, _>(compose(f, g), compose(h, i), x.clone())
1441 == bimap::<PairBrand, _, _, _, _, _, _>(
1442 f,
1443 h,
1444 bimap::<PairBrand, _, _, _, _, _, _>(g, i, x),
1445 )
1446 }
1447
1448 #[quickcheck]
1452 fn functor_identity(
1453 first: String,
1454 second: i32,
1455 ) -> bool {
1456 let x = Pair(first, second);
1457 map::<PairWithFirstBrand<String>, _, _, _>(identity, x.clone()) == x
1458 }
1459
1460 #[quickcheck]
1462 fn functor_composition(
1463 first: String,
1464 second: i32,
1465 ) -> bool {
1466 let x = Pair(first, second);
1467 let f = |x: i32| x.wrapping_add(1);
1468 let g = |x: i32| x.wrapping_mul(2);
1469 map::<PairWithFirstBrand<String>, _, _, _>(compose(f, g), x.clone())
1470 == map::<PairWithFirstBrand<String>, _, _, _>(
1471 f,
1472 map::<PairWithFirstBrand<String>, _, _, _>(g, x),
1473 )
1474 }
1475
1476 #[quickcheck]
1480 fn applicative_identity(
1481 first: String,
1482 second: i32,
1483 ) -> bool {
1484 let v = Pair(first, second);
1485 apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1486 pure::<PairWithFirstBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1487 v.clone(),
1488 ) == v
1489 }
1490
1491 #[quickcheck]
1493 fn applicative_homomorphism(x: i32) -> bool {
1494 let f = |x: i32| x.wrapping_mul(2);
1495 apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1496 pure::<PairWithFirstBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1497 pure::<PairWithFirstBrand<String>, _>(x),
1498 ) == pure::<PairWithFirstBrand<String>, _>(f(x))
1499 }
1500
1501 #[quickcheck]
1503 fn applicative_composition(
1504 w_first: String,
1505 w_second: i32,
1506 u_seed: i32,
1507 v_seed: i32,
1508 ) -> bool {
1509 let w = Pair(w_first, w_second);
1510
1511 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1512 let u = pure::<PairWithFirstBrand<String>, _>(u_fn);
1513
1514 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1515 let v = pure::<PairWithFirstBrand<String>, _>(v_fn);
1516
1517 let vw = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(v.clone(), w.clone());
1519 let rhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(u.clone(), vw);
1520
1521 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1523 let f = f.clone();
1524 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1525 let f = f.clone();
1526 let g = g.clone();
1527 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1528 })
1529 });
1530
1531 let pure_compose = pure::<PairWithFirstBrand<String>, _>(compose_fn);
1532 let u_applied = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(pure_compose, u);
1533 let uv = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(u_applied, v);
1534 let lhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(uv, w);
1535
1536 lhs == rhs
1537 }
1538
1539 #[quickcheck]
1541 fn applicative_interchange(
1542 y: i32,
1543 u_seed: i32,
1544 ) -> bool {
1545 let f = move |x: i32| x.wrapping_mul(u_seed);
1547 let u = pure::<PairWithFirstBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1548
1549 let lhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1550 u.clone(),
1551 pure::<PairWithFirstBrand<String>, _>(y),
1552 );
1553
1554 let rhs_fn =
1555 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1556 let rhs = apply::<RcFnBrand, PairWithFirstBrand<String>, _, _>(
1557 pure::<PairWithFirstBrand<String>, _>(rhs_fn),
1558 u,
1559 );
1560
1561 lhs == rhs
1562 }
1563
1564 #[quickcheck]
1568 fn monad_left_identity(a: i32) -> bool {
1569 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1570 bind::<PairWithFirstBrand<String>, _, _, _>(pure::<PairWithFirstBrand<String>, _>(a), f)
1571 == f(a)
1572 }
1573
1574 #[quickcheck]
1576 fn monad_right_identity(
1577 first: String,
1578 second: i32,
1579 ) -> bool {
1580 let m = Pair(first, second);
1581 bind::<PairWithFirstBrand<String>, _, _, _>(
1582 m.clone(),
1583 pure::<PairWithFirstBrand<String>, _>,
1584 ) == m
1585 }
1586
1587 #[quickcheck]
1589 fn monad_associativity(
1590 first: String,
1591 second: i32,
1592 ) -> bool {
1593 let m = Pair(first, second);
1594 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1595 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1596 bind::<PairWithFirstBrand<String>, _, _, _>(
1597 bind::<PairWithFirstBrand<String>, _, _, _>(m.clone(), f),
1598 g,
1599 ) == bind::<PairWithFirstBrand<String>, _, _, _>(m, |x| {
1600 bind::<PairWithFirstBrand<String>, _, _, _>(f(x), g)
1601 })
1602 }
1603
1604 #[test]
1608 fn par_fold_map_pair_with_first() {
1609 let x = Pair("a".to_string(), 1);
1610 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1611 assert_eq!(
1612 par_fold_map::<ArcFnBrand, PairWithFirstBrand<String>, _, _>(f, x),
1613 "1".to_string()
1614 );
1615 }
1616
1617 #[test]
1619 fn par_fold_right_pair_with_first() {
1620 let x = Pair("a".to_string(), 1);
1621 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1622 assert_eq!(par_fold_right::<ArcFnBrand, PairWithFirstBrand<String>, _, _>(f, 10, x), 11);
1623 }
1624
1625 #[test]
1629 fn par_fold_map_pair_with_second() {
1630 let x = Pair(1, "a".to_string());
1631 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1632 assert_eq!(
1633 par_fold_map::<ArcFnBrand, PairWithSecondBrand<String>, _, _>(f, x),
1634 "1".to_string()
1635 );
1636 }
1637
1638 #[test]
1640 fn par_fold_right_pair_with_second() {
1641 let x = Pair(1, "a".to_string());
1642 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1643 assert_eq!(par_fold_right::<ArcFnBrand, PairWithSecondBrand<String>, _, _>(f, 10, x), 11);
1644 }
1645}