1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::{
11 PairBrand,
12 PairFirstAppliedBrand,
13 PairSecondAppliedBrand,
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 ParFoldable,
28 Pointed,
29 Semiapplicative,
30 Semigroup,
31 Semimonad,
32 SendCloneableFn,
33 Traversable,
34 },
35 impl_kind,
36 kinds::*,
37 },
38 fp_macros::*,
39 };
40
41 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
56 #[document_fields("The first value.", "The second value.")]
58 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
61 pub struct Pair<First, Second>(pub First, pub Second);
62
63 impl_kind! {
64 for PairBrand {
65 type Of<First,Second> = Pair<First, Second>;
66 }
67 }
68
69 impl_kind! {
70 for PairBrand {
71 type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
72 }
73 }
74
75 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
76 #[document_parameters("The pair instance.")]
77 impl<First, Second> Pair<First, Second> {
78 #[document_signature]
82 #[document_type_parameters(
84 "The type of the mapped first value.",
85 "The type of the mapped second value."
86 )]
87 #[document_parameters(
89 "The function to apply to the first value.",
90 "The function to apply to the second value."
91 )]
92 #[document_returns("A new pair containing the mapped values.")]
94 #[document_examples]
96 pub fn bimap<B, D>(
104 self,
105 f: impl FnOnce(First) -> B,
106 g: impl FnOnce(Second) -> D,
107 ) -> Pair<B, D> {
108 Pair(f(self.0), g(self.1))
109 }
110
111 #[document_signature]
115 #[document_type_parameters("The type of the mapped first value.")]
117 #[document_parameters("The function to apply to the first value.")]
119 #[document_returns("A new pair with the transformed first value.")]
121 #[document_examples]
123 pub fn map_first<B>(
131 self,
132 f: impl FnOnce(First) -> B,
133 ) -> Pair<B, Second> {
134 Pair(f(self.0), self.1)
135 }
136
137 #[document_signature]
141 #[document_type_parameters("The type of the mapped second value.")]
143 #[document_parameters("The function to apply to the second value.")]
145 #[document_returns("A new pair with the transformed second value.")]
147 #[document_examples]
149 pub fn map_second<D>(
157 self,
158 g: impl FnOnce(Second) -> D,
159 ) -> Pair<First, D> {
160 Pair(self.0, g(self.1))
161 }
162
163 #[document_signature]
168 #[document_type_parameters("The result type.")]
170 #[document_parameters(
172 "The function to apply to the first value.",
173 "The function to apply to the second value.",
174 "The function to combine the results."
175 )]
176 #[document_returns("The combined result.")]
178 #[document_examples]
180 pub fn fold<C>(
189 self,
190 f: impl FnOnce(First) -> C,
191 g: impl FnOnce(Second) -> C,
192 combine: impl FnOnce(C, C) -> C,
193 ) -> C {
194 combine(f(self.0), g(self.1))
195 }
196
197 #[document_signature]
201 #[document_type_parameters("The accumulator type.")]
203 #[document_parameters(
205 "The step function for the first value.",
206 "The step function for the second value.",
207 "The initial accumulator."
208 )]
209 #[document_returns("The result of folding: `f(first, g(second, z))`.")]
211 #[document_examples]
213 pub fn bi_fold_right<C>(
221 self,
222 f: impl FnOnce(First, C) -> C,
223 g: impl FnOnce(Second, C) -> C,
224 z: C,
225 ) -> C {
226 f(self.0, g(self.1, z))
227 }
228
229 #[document_signature]
233 #[document_type_parameters("The accumulator type.")]
235 #[document_parameters(
237 "The step function for the first value.",
238 "The step function for the second value.",
239 "The initial accumulator."
240 )]
241 #[document_returns("The result of folding: `g(f(z, first), second)`.")]
243 #[document_examples]
245 pub fn bi_fold_left<C>(
253 self,
254 f: impl FnOnce(C, First) -> C,
255 g: impl FnOnce(C, Second) -> C,
256 z: C,
257 ) -> C {
258 g(f(z, self.0), self.1)
259 }
260
261 #[document_signature]
265 #[document_type_parameters("The monoid type.")]
267 #[document_parameters(
269 "The function mapping the first value to the monoid.",
270 "The function mapping the second value to the monoid."
271 )]
272 #[document_returns("The combined monoid value.")]
274 #[document_examples]
276 pub fn bi_fold_map<M: Semigroup>(
284 self,
285 f: impl FnOnce(First) -> M,
286 g: impl FnOnce(Second) -> M,
287 ) -> M {
288 Semigroup::append(f(self.0), g(self.1))
289 }
290 }
291
292 #[document_type_parameters(
293 "The lifetime of the values.",
294 "The type of the first value.",
295 "The type of the second value."
296 )]
297 #[document_parameters("The pair instance.")]
298 impl<'a, First: 'a, Second: 'a> Pair<First, Second> {
299 #[document_signature]
303 #[document_type_parameters(
305 "The output type for the first value.",
306 "The output type for the second value.",
307 "The applicative context."
308 )]
309 #[document_parameters(
311 "The function for the first value.",
312 "The function for the second value."
313 )]
314 #[document_returns("A pair of the transformed values wrapped in the applicative context.")]
316 #[document_examples]
318 pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
330 self,
331 f: impl Fn(First) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
332 g: impl Fn(Second) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
333 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Pair<C, D>>)
334 where
335 Pair<C, D>: Clone, {
336 F::lift2(|c, d| Pair(c, d), f(self.0), g(self.1))
337 }
338 }
339
340 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
341 #[document_parameters("The pair instance.")]
342 impl<First: Semigroup, Second> Pair<First, Second> {
343 #[document_signature]
348 #[document_type_parameters("The type of the new second value.")]
350 #[document_parameters("The function to apply to the second value.")]
352 #[document_returns(
354 "A new pair where the first values are combined and the second value is transformed."
355 )]
356 #[document_examples]
358 pub fn bind<C>(
368 self,
369 f: impl FnOnce(Second) -> Pair<First, C>,
370 ) -> Pair<First, C> {
371 let Pair(first, second) = self;
372 let Pair(next_first, next_second) = f(second);
373 Pair(Semigroup::append(first, next_first), next_second)
374 }
375 }
376
377 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
378 #[document_parameters("The pair instance.")]
379 impl<First, Second: Semigroup> Pair<First, Second> {
380 #[document_signature]
385 #[document_type_parameters("The type of the new first value.")]
387 #[document_parameters("The function to apply to the first value.")]
389 #[document_returns(
391 "A new pair where the first value is transformed and the second values are combined."
392 )]
393 #[document_examples]
395 pub fn bind_first<C>(
405 self,
406 f: impl FnOnce(First) -> Pair<C, Second>,
407 ) -> Pair<C, Second> {
408 let Pair(first, second) = self;
409 let Pair(next_first, next_second) = f(first);
410 Pair(next_first, Semigroup::append(second, next_second))
411 }
412 }
413
414 impl Bifunctor for PairBrand {
415 #[document_signature]
419 #[document_type_parameters(
421 "The lifetime of the values.",
422 "The type of the first value.",
423 "The type of the mapped first value.",
424 "The type of the second value.",
425 "The type of the mapped second value."
426 )]
427 #[document_parameters(
429 "The function to apply to the first value.",
430 "The function to apply to the second value.",
431 "The pair to map over."
432 )]
433 #[document_returns("A new pair containing the mapped values.")]
435 #[document_examples]
436 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
449 f: impl Fn(A) -> B + 'a,
450 g: impl Fn(C) -> D + 'a,
451 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
452 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
453 p.bimap(f, g)
454 }
455 }
456
457 impl Bifoldable for PairBrand {
458 #[document_signature]
462 #[document_type_parameters(
464 "The lifetime of the values.",
465 "The brand of the cloneable function to use.",
466 "The type of the first value.",
467 "The type of the second value.",
468 "The accumulator type."
469 )]
470 #[document_parameters(
472 "The step function for the first value.",
473 "The step function for the second value.",
474 "The initial accumulator.",
475 "The pair to fold."
476 )]
477 #[document_returns("`f(a, g(b, z))`.")]
479 #[document_examples]
480 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
495 f: impl Fn(A, C) -> C + 'a,
496 g: impl Fn(B, C) -> C + 'a,
497 z: C,
498 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
499 ) -> C {
500 p.bi_fold_right(f, g, z)
501 }
502
503 #[document_signature]
507 #[document_type_parameters(
509 "The lifetime of the values.",
510 "The brand of the cloneable function to use.",
511 "The type of the first value.",
512 "The type of the second value.",
513 "The accumulator type."
514 )]
515 #[document_parameters(
517 "The step function for the first value.",
518 "The step function for the second value.",
519 "The initial accumulator.",
520 "The pair to fold."
521 )]
522 #[document_returns("`g(f(z, a), b)`.")]
524 #[document_examples]
525 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
540 f: impl Fn(C, A) -> C + 'a,
541 g: impl Fn(C, B) -> C + 'a,
542 z: C,
543 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
544 ) -> C {
545 p.bi_fold_left(f, g, z)
546 }
547
548 #[document_signature]
552 #[document_type_parameters(
554 "The lifetime of the values.",
555 "The brand of the cloneable function to use.",
556 "The type of the first value.",
557 "The type of the second value.",
558 "The monoid type."
559 )]
560 #[document_parameters(
562 "The function mapping the first value to the monoid.",
563 "The function mapping the second value to the monoid.",
564 "The pair to fold."
565 )]
566 #[document_returns("`Semigroup::append(f(a), g(b))`.")]
568 #[document_examples]
569 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
587 f: impl Fn(A) -> M + 'a,
588 g: impl Fn(B) -> M + 'a,
589 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
590 ) -> M
591 where
592 M: Monoid + 'a, {
593 p.bi_fold_map(f, g)
594 }
595 }
596
597 impl Bitraversable for PairBrand {
598 #[document_signature]
603 #[document_type_parameters(
605 "The lifetime of the values.",
606 "The type of the first value.",
607 "The type of the second value.",
608 "The output type for the first value.",
609 "The output type for the second value.",
610 "The applicative context."
611 )]
612 #[document_parameters(
614 "The function applied to the first value.",
615 "The function applied to the second value.",
616 "The pair to traverse."
617 )]
618 #[document_returns("`lift2(Pair, f(a), g(b))`.")]
620 #[document_examples]
621 fn bi_traverse<
640 'a,
641 A: 'a + Clone,
642 B: 'a + Clone,
643 C: 'a + Clone,
644 D: 'a + Clone,
645 F: Applicative,
646 >(
647 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
648 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
649 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
650 ) -> 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>)>)
651 {
652 p.bi_traverse::<C, D, F>(f, g)
653 }
654 }
655
656 impl_kind! {
659 #[document_type_parameters("The type of the first value in the pair.")]
660 impl<First: 'static> for PairFirstAppliedBrand<First> {
661 type Of<'a, A: 'a>: 'a = Pair<First, A>;
662 }
663 }
664
665 #[document_type_parameters("The type of the first value in the pair.")]
666 impl<First: 'static> Functor for PairFirstAppliedBrand<First> {
667 #[document_signature]
671 #[document_type_parameters(
673 "The lifetime of the values.",
674 "The type of the second value.",
675 "The type of the result of applying the function."
676 )]
677 #[document_parameters(
679 "The function to apply to the second value.",
680 "The pair to map over."
681 )]
682 #[document_returns(
684 "A new pair containing the result of applying the function to the second value."
685 )]
686 #[document_examples]
687 fn map<'a, A: 'a, B: 'a>(
698 func: impl Fn(A) -> B + 'a,
699 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
700 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
701 fa.map_second(func)
702 }
703 }
704
705 #[document_type_parameters("The type of the first value in the pair.")]
706 impl<First: Clone + 'static> Lift for PairFirstAppliedBrand<First>
707 where
708 First: Semigroup,
709 {
710 #[document_signature]
714 #[document_type_parameters(
716 "The lifetime of the values.",
717 "The type of the first second value.",
718 "The type of the second second value.",
719 "The type of the result second value."
720 )]
721 #[document_parameters(
723 "The binary function to apply to the second values.",
724 "The first pair.",
725 "The second pair."
726 )]
727 #[document_returns(
729 "A new pair where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
730 )]
731 #[document_examples]
732 fn lift2<'a, A, B, C>(
750 func: impl Fn(A, B) -> C + 'a,
751 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
752 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
753 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
754 where
755 A: Clone + 'a,
756 B: Clone + 'a,
757 C: 'a, {
758 let Pair(fa_first, fa_second) = fa;
759 let Pair(fb_first, fb_second) = fb;
760 Pair(Semigroup::append(fa_first, fb_first), func(fa_second, fb_second))
761 }
762 }
763
764 #[document_type_parameters("The type of the first value in the pair.")]
765 impl<First: Clone + 'static> Pointed for PairFirstAppliedBrand<First>
766 where
767 First: Monoid,
768 {
769 #[document_signature]
773 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
775 #[document_parameters("The value to wrap.")]
777 #[document_returns("A pair containing the empty value of the first type and `a`.")]
779 #[document_examples]
781 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
792 Pair(Monoid::empty(), a)
793 }
794 }
795
796 #[document_type_parameters("The type of the first value in the pair.")]
797 impl<First: Clone + Semigroup + 'static> ApplyFirst for PairFirstAppliedBrand<First> {}
798
799 #[document_type_parameters("The type of the first value in the pair.")]
800 impl<First: Clone + Semigroup + 'static> ApplySecond for PairFirstAppliedBrand<First> {}
801
802 #[document_type_parameters("The type of the first value in the pair.")]
803 impl<First: Clone + 'static> Semiapplicative for PairFirstAppliedBrand<First>
804 where
805 First: Semigroup,
806 {
807 #[document_signature]
811 #[document_type_parameters(
813 "The lifetime of the values.",
814 "The brand of the cloneable function wrapper.",
815 "The type of the input value.",
816 "The type of the output value."
817 )]
818 #[document_parameters(
820 "The pair containing the function.",
821 "The pair containing the value."
822 )]
823 #[document_returns(
825 "A new pair where the first values are combined and the function is applied to the second value."
826 )]
827 #[document_examples]
828 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
843 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
844 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
845 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
846 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
847 }
848 }
849
850 #[document_type_parameters("The type of the first value in the pair.")]
851 impl<First: Clone + 'static> Semimonad for PairFirstAppliedBrand<First>
852 where
853 First: Semigroup,
854 {
855 #[document_signature]
859 #[document_type_parameters(
861 "The lifetime of the values.",
862 "The type of the result of the first computation.",
863 "The type of the result of the second computation."
864 )]
865 #[document_parameters("The first pair.", "The function to apply to the second value.")]
867 #[document_returns("A new pair where the first values are combined.")]
869 #[document_examples]
871 fn bind<'a, A: 'a, B: 'a>(
888 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
889 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
890 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
891 ma.bind(func)
892 }
893 }
894
895 #[document_type_parameters("The type of the first value in the pair.")]
896 impl<First: 'static> Foldable for PairFirstAppliedBrand<First> {
897 #[document_signature]
901 #[document_type_parameters(
903 "The lifetime of the values.",
904 "The brand of the cloneable function to use.",
905 "The type of the elements in the structure.",
906 "The type of the accumulator."
907 )]
908 #[document_parameters("The folding function.", "The initial value.", "The pair to fold.")]
910 #[document_returns("`func(a, initial)`.")]
912 #[document_examples]
914 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
928 func: impl Fn(A, B) -> B + 'a,
929 initial: B,
930 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
931 ) -> B
932 where
933 FnBrand: CloneableFn + 'a, {
934 func(fa.1, initial)
935 }
936
937 #[document_signature]
941 #[document_type_parameters(
943 "The lifetime of the values.",
944 "The brand of the cloneable function to use.",
945 "The type of the elements in the structure.",
946 "The type of the accumulator."
947 )]
948 #[document_parameters(
950 "The function to apply to the accumulator and each element.",
951 "The initial value of the accumulator.",
952 "The identity to fold."
953 )]
954 #[document_returns("`func(initial, a)`.")]
956 #[document_examples]
957 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
971 func: impl Fn(B, A) -> B + 'a,
972 initial: B,
973 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
974 ) -> B
975 where
976 FnBrand: CloneableFn + 'a, {
977 func(initial, fa.1)
978 }
979
980 #[document_signature]
984 #[document_type_parameters(
986 "The lifetime of the values.",
987 "The brand of the cloneable function to use.",
988 "The type of the elements in the structure.",
989 "The type of the monoid."
990 )]
991 #[document_parameters("The mapping function.", "The pair to fold.")]
993 #[document_returns("`func(a)`.")]
995 #[document_examples]
997 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1011 func: impl Fn(A) -> M + 'a,
1012 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1013 ) -> M
1014 where
1015 M: Monoid + 'a,
1016 FnBrand: CloneableFn + 'a, {
1017 func(fa.1)
1018 }
1019 }
1020
1021 #[document_type_parameters("The type of the first value in the pair.")]
1022 impl<First: Clone + 'static> Traversable for PairFirstAppliedBrand<First> {
1023 #[document_signature]
1027 #[document_type_parameters(
1029 "The lifetime of the values.",
1030 "The type of the elements in the traversable structure.",
1031 "The type of the elements in the resulting traversable structure.",
1032 "The applicative context."
1033 )]
1034 #[document_parameters(
1036 "The function to apply to each element, returning a value in an applicative context.",
1037 "The pair to traverse."
1038 )]
1039 #[document_returns("The pair wrapped in the applicative context.")]
1041 #[document_examples]
1042 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1056 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1057 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1058 ) -> 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>)>)
1059 where
1060 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1061 let Pair(first, second) = ta;
1062 F::map(move |b| Pair(first.clone(), b), func(second))
1063 }
1064
1065 #[document_signature]
1069 #[document_type_parameters(
1071 "The lifetime of the values.",
1072 "The type of the elements in the traversable structure.",
1073 "The applicative context."
1074 )]
1075 #[document_parameters("The pair containing the applicative value.")]
1077 #[document_returns("The pair wrapped in the applicative context.")]
1079 #[document_examples]
1081 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1095 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>)>)
1096 ) -> 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>)>)
1097 where
1098 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1099 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1100 let Pair(first, second) = ta;
1101 F::map(move |a| Pair(first.clone(), a), second)
1102 }
1103 }
1104
1105 #[document_type_parameters("The type of the first value in the pair.")]
1106 impl<First: 'static> ParFoldable for PairFirstAppliedBrand<First> {
1107 #[document_signature]
1111 #[document_type_parameters(
1113 "The lifetime of the values.",
1114 "The brand of the cloneable function wrapper.",
1115 "The element type.",
1116 "The monoid type."
1117 )]
1118 #[document_parameters(
1120 "The thread-safe function to map each element to a monoid.",
1121 "The pair to fold."
1122 )]
1123 #[document_returns("The combined monoid value.")]
1125 #[document_examples]
1126 fn par_fold_map<'a, FnBrand, A, M>(
1142 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1143 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1144 ) -> M
1145 where
1146 FnBrand: 'a + SendCloneableFn,
1147 A: 'a + Clone + Send + Sync,
1148 M: Monoid + Send + Sync + 'a, {
1149 func(fa.1)
1150 }
1151
1152 #[document_signature]
1156 #[document_type_parameters(
1158 "The lifetime of the values.",
1159 "The brand of the cloneable function wrapper.",
1160 "The element type.",
1161 "The accumulator type."
1162 )]
1163 #[document_parameters(
1165 "The thread-safe function to apply to each element and the accumulator.",
1166 "The initial value.",
1167 "The pair to fold."
1168 )]
1169 #[document_returns("The final accumulator value.")]
1171 #[document_examples]
1172 fn par_fold_right<'a, FnBrand, A, B>(
1185 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1186 initial: B,
1187 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1188 ) -> B
1189 where
1190 FnBrand: 'a + SendCloneableFn,
1191 A: 'a + Clone + Send + Sync,
1192 B: Send + Sync + 'a, {
1193 func((fa.1, initial))
1194 }
1195 }
1196 impl_kind! {
1199 #[document_type_parameters("The type of the second value in the pair.")]
1200 impl<Second: 'static> for PairSecondAppliedBrand<Second> {
1201 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
1202 }
1203 }
1204
1205 #[document_type_parameters("The type of the second value in the pair.")]
1206 impl<Second: 'static> Functor for PairSecondAppliedBrand<Second> {
1207 #[document_signature]
1211 #[document_type_parameters(
1213 "The lifetime of the values.",
1214 "The type of the first value.",
1215 "The type of the result of applying the function."
1216 )]
1217 #[document_parameters("The function to apply to the first value.", "The pair to map over.")]
1219 #[document_returns(
1221 "A new pair containing the result of applying the function to the first value."
1222 )]
1223 #[document_examples]
1225 fn map<'a, A: 'a, B: 'a>(
1236 func: impl Fn(A) -> B + 'a,
1237 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1238 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1239 fa.map_first(func)
1240 }
1241 }
1242
1243 #[document_type_parameters("The type of the second value in the pair.")]
1244 impl<Second: Clone + 'static> Lift for PairSecondAppliedBrand<Second>
1245 where
1246 Second: Semigroup,
1247 {
1248 #[document_signature]
1252 #[document_type_parameters(
1254 "The lifetime of the values.",
1255 "The type of the first first value.",
1256 "The type of the second first value.",
1257 "The type of the result first value."
1258 )]
1259 #[document_parameters(
1261 "The binary function to apply to the first values.",
1262 "The first pair.",
1263 "The second pair."
1264 )]
1265 #[document_returns(
1267 "A new pair where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
1268 )]
1269 #[document_examples]
1270 fn lift2<'a, A, B, C>(
1288 func: impl Fn(A, B) -> C + 'a,
1289 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1290 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1291 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1292 where
1293 A: Clone + 'a,
1294 B: Clone + 'a,
1295 C: 'a, {
1296 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
1297 }
1298 }
1299
1300 #[document_type_parameters("The type of the second value in the pair.")]
1301 impl<Second: Clone + 'static> Pointed for PairSecondAppliedBrand<Second>
1302 where
1303 Second: Monoid,
1304 {
1305 #[document_signature]
1309 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1311 #[document_parameters("The value to wrap.")]
1313 #[document_returns("A pair containing `a` and the empty value of the second type.")]
1315 #[document_examples]
1317 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1328 Pair(a, Monoid::empty())
1329 }
1330 }
1331
1332 #[document_type_parameters("The type of the second value in the pair.")]
1333 impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairSecondAppliedBrand<Second> {}
1334
1335 #[document_type_parameters("The type of the second value in the pair.")]
1336 impl<Second: Clone + Semigroup + 'static> ApplySecond for PairSecondAppliedBrand<Second> {}
1337
1338 #[document_type_parameters("The type of the second value in the pair.")]
1339 impl<Second: Clone + 'static> Semiapplicative for PairSecondAppliedBrand<Second>
1340 where
1341 Second: Semigroup,
1342 {
1343 #[document_signature]
1347 #[document_type_parameters(
1349 "The lifetime of the values.",
1350 "The brand of the cloneable function wrapper.",
1351 "The type of the input value.",
1352 "The type of the output value."
1353 )]
1354 #[document_parameters(
1356 "The pair containing the function (in Err).",
1357 "The pair containing the value (in Err)."
1358 )]
1359 #[document_returns(
1361 "`Err(f(a))` if both are `Err`, otherwise the first success encountered."
1362 )]
1363 #[document_examples]
1364 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1379 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1380 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1381 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1382 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1383 }
1384 }
1385
1386 #[document_type_parameters("The type of the second value in the pair.")]
1387 impl<Second: Clone + 'static> Semimonad for PairSecondAppliedBrand<Second>
1388 where
1389 Second: Semigroup,
1390 {
1391 #[document_signature]
1395 #[document_type_parameters(
1397 "The lifetime of the values.",
1398 "The type of the result of the first computation.",
1399 "The type of the result of the second computation."
1400 )]
1401 #[document_parameters("The first result.", "The function to apply to the error value.")]
1403 #[document_returns(
1405 "The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
1406 )]
1407 #[document_examples]
1409 fn bind<'a, A: 'a, B: 'a>(
1426 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1427 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1428 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1429 ma.bind_first(func)
1430 }
1431 }
1432
1433 #[document_type_parameters("The type of the second value in the pair.")]
1434 impl<Second: 'static> Foldable for PairSecondAppliedBrand<Second> {
1435 #[document_signature]
1439 #[document_type_parameters(
1441 "The lifetime of the values.",
1442 "The brand of the cloneable function to use.",
1443 "The type of the elements in the structure.",
1444 "The type of the accumulator."
1445 )]
1446 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1448 #[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
1450 #[document_examples]
1452 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1466 func: impl Fn(A, B) -> B + 'a,
1467 initial: B,
1468 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1469 ) -> B
1470 where
1471 FnBrand: CloneableFn + 'a, {
1472 func(fa.0, initial)
1473 }
1474
1475 #[document_signature]
1479 #[document_type_parameters(
1481 "The lifetime of the values.",
1482 "The brand of the cloneable function to use.",
1483 "The type of the elements in the structure.",
1484 "The type of the accumulator."
1485 )]
1486 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1488 #[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
1490 #[document_examples]
1492 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1506 func: impl Fn(B, A) -> B + 'a,
1507 initial: B,
1508 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1509 ) -> B
1510 where
1511 FnBrand: CloneableFn + 'a, {
1512 func(initial, fa.0)
1513 }
1514
1515 #[document_signature]
1519 #[document_type_parameters(
1521 "The lifetime of the values.",
1522 "The brand of the cloneable function to use.",
1523 "The type of the elements in the structure.",
1524 "The type of the monoid."
1525 )]
1526 #[document_parameters("The mapping function.", "The result to fold.")]
1528 #[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
1530 #[document_examples]
1532 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1549 func: impl Fn(A) -> M + 'a,
1550 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1551 ) -> M
1552 where
1553 M: Monoid + 'a,
1554 FnBrand: CloneableFn + 'a, {
1555 func(fa.0)
1556 }
1557 }
1558
1559 #[document_type_parameters("The type of the second value in the pair.")]
1560 impl<Second: Clone + 'static> Traversable for PairSecondAppliedBrand<Second> {
1561 #[document_signature]
1565 #[document_type_parameters(
1567 "The lifetime of the values.",
1568 "The type of the elements in the traversable structure.",
1569 "The type of the elements in the resulting traversable structure.",
1570 "The applicative context."
1571 )]
1572 #[document_parameters("The function to apply.", "The result to traverse.")]
1574 #[document_returns("The result wrapped in the applicative context.")]
1576 #[document_examples]
1578 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1592 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1593 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1594 ) -> 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>)>)
1595 where
1596 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1597 let Pair(first, second) = ta;
1598 F::map(move |b| Pair(b, second.clone()), func(first))
1599 }
1600
1601 #[document_signature]
1605 #[document_type_parameters(
1607 "The lifetime of the values.",
1608 "The type of the elements in the traversable structure.",
1609 "The applicative context."
1610 )]
1611 #[document_parameters("The result containing the applicative value.")]
1613 #[document_returns("The result wrapped in the applicative context.")]
1615 #[document_examples]
1617 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1631 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>)>)
1632 ) -> 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>)>)
1633 where
1634 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1635 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1636 let Pair(first, second) = ta;
1637 F::map(move |a| Pair(a, second.clone()), first)
1638 }
1639 }
1640
1641 #[document_type_parameters("The type of the second value in the pair.")]
1642 impl<Second: 'static> ParFoldable for PairSecondAppliedBrand<Second> {
1643 #[document_signature]
1647 #[document_type_parameters(
1649 "The lifetime of the values.",
1650 "The brand of the cloneable function wrapper.",
1651 "The element type.",
1652 "The monoid type."
1653 )]
1654 #[document_parameters(
1656 "The thread-safe function to map each element to a monoid.",
1657 "The pair to fold."
1658 )]
1659 #[document_returns("The combined monoid value.")]
1661 #[document_examples]
1662 fn par_fold_map<'a, FnBrand, A, M>(
1678 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1679 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1680 ) -> M
1681 where
1682 FnBrand: 'a + SendCloneableFn,
1683 A: 'a + Clone + Send + Sync,
1684 M: Monoid + Send + Sync + 'a, {
1685 func(fa.0)
1686 }
1687
1688 #[document_signature]
1692 #[document_type_parameters(
1694 "The lifetime of the values.",
1695 "The brand of the cloneable function wrapper.",
1696 "The element type.",
1697 "The accumulator type."
1698 )]
1699 #[document_parameters(
1701 "The thread-safe function to apply to each element and the accumulator.",
1702 "The initial value.",
1703 "The pair to fold."
1704 )]
1705 #[document_returns("The final accumulator value.")]
1707 #[document_examples]
1708 fn par_fold_right<'a, FnBrand, A, B>(
1721 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1722 initial: B,
1723 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1724 ) -> B
1725 where
1726 FnBrand: 'a + SendCloneableFn,
1727 A: 'a + Clone + Send + Sync,
1728 B: Send + Sync + 'a, {
1729 func((fa.0, initial))
1730 }
1731 }
1732}
1733pub use inner::*;
1734
1735#[cfg(test)]
1736mod tests {
1737 use {
1738 super::inner::*,
1739 crate::{
1740 brands::*,
1741 classes::{
1742 CloneableFn,
1743 bifunctor::*,
1744 },
1745 functions::*,
1746 },
1747 quickcheck_macros::quickcheck,
1748 };
1749
1750 #[test]
1754 fn test_bimap() {
1755 let x = Pair(1, 5);
1756 assert_eq!(bimap::<PairBrand, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1757 }
1758
1759 #[quickcheck]
1763 fn bifunctor_identity(
1764 first: String,
1765 second: i32,
1766 ) -> bool {
1767 let x = Pair(first, second);
1768 bimap::<PairBrand, _, _, _, _>(identity, identity, x.clone()) == x
1769 }
1770
1771 #[quickcheck]
1773 fn bifunctor_composition(
1774 first: i32,
1775 second: i32,
1776 ) -> bool {
1777 let x = Pair(first, second);
1778 let f = |x: i32| x.wrapping_add(1);
1779 let g = |x: i32| x.wrapping_mul(2);
1780 let h = |x: i32| x.wrapping_sub(1);
1781 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1782
1783 bimap::<PairBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1784 == bimap::<PairBrand, _, _, _, _>(f, h, bimap::<PairBrand, _, _, _, _>(g, i, x))
1785 }
1786
1787 #[quickcheck]
1791 fn functor_identity(
1792 first: String,
1793 second: i32,
1794 ) -> bool {
1795 let x = Pair(first, second);
1796 map::<PairFirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1797 }
1798
1799 #[quickcheck]
1801 fn functor_composition(
1802 first: String,
1803 second: i32,
1804 ) -> bool {
1805 let x = Pair(first, second);
1806 let f = |x: i32| x.wrapping_add(1);
1807 let g = |x: i32| x.wrapping_mul(2);
1808 map::<PairFirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1809 == map::<PairFirstAppliedBrand<String>, _, _>(
1810 f,
1811 map::<PairFirstAppliedBrand<String>, _, _>(g, x),
1812 )
1813 }
1814
1815 #[quickcheck]
1819 fn applicative_identity(
1820 first: String,
1821 second: i32,
1822 ) -> bool {
1823 let v = Pair(first, second);
1824 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1825 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1826 v.clone(),
1827 ) == v
1828 }
1829
1830 #[quickcheck]
1832 fn applicative_homomorphism(x: i32) -> bool {
1833 let f = |x: i32| x.wrapping_mul(2);
1834 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1835 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1836 pure::<PairFirstAppliedBrand<String>, _>(x),
1837 ) == pure::<PairFirstAppliedBrand<String>, _>(f(x))
1838 }
1839
1840 #[quickcheck]
1842 fn applicative_composition(
1843 w_first: String,
1844 w_second: i32,
1845 u_seed: i32,
1846 v_seed: i32,
1847 ) -> bool {
1848 let w = Pair(w_first, w_second);
1849
1850 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1851 let u = pure::<PairFirstAppliedBrand<String>, _>(u_fn);
1852
1853 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1854 let v = pure::<PairFirstAppliedBrand<String>, _>(v_fn);
1855
1856 let vw = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1858 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u.clone(), vw);
1859
1860 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1862 let f = f.clone();
1863 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1864 let f = f.clone();
1865 let g = g.clone();
1866 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1867 })
1868 });
1869
1870 let pure_compose = pure::<PairFirstAppliedBrand<String>, _>(compose_fn);
1871 let u_applied = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(pure_compose, u);
1872 let uv = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u_applied, v);
1873 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(uv, w);
1874
1875 lhs == rhs
1876 }
1877
1878 #[quickcheck]
1880 fn applicative_interchange(
1881 y: i32,
1882 u_seed: i32,
1883 ) -> bool {
1884 let f = move |x: i32| x.wrapping_mul(u_seed);
1886 let u = pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1887
1888 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1889 u.clone(),
1890 pure::<PairFirstAppliedBrand<String>, _>(y),
1891 );
1892
1893 let rhs_fn =
1894 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1895 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1896 pure::<PairFirstAppliedBrand<String>, _>(rhs_fn),
1897 u,
1898 );
1899
1900 lhs == rhs
1901 }
1902
1903 #[quickcheck]
1907 fn monad_left_identity(a: i32) -> bool {
1908 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1909 bind::<PairFirstAppliedBrand<String>, _, _>(pure::<PairFirstAppliedBrand<String>, _>(a), f)
1910 == f(a)
1911 }
1912
1913 #[quickcheck]
1915 fn monad_right_identity(
1916 first: String,
1917 second: i32,
1918 ) -> bool {
1919 let m = Pair(first, second);
1920 bind::<PairFirstAppliedBrand<String>, _, _>(
1921 m.clone(),
1922 pure::<PairFirstAppliedBrand<String>, _>,
1923 ) == m
1924 }
1925
1926 #[quickcheck]
1928 fn monad_associativity(
1929 first: String,
1930 second: i32,
1931 ) -> bool {
1932 let m = Pair(first, second);
1933 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1934 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1935 bind::<PairFirstAppliedBrand<String>, _, _>(
1936 bind::<PairFirstAppliedBrand<String>, _, _>(m.clone(), f),
1937 g,
1938 ) == bind::<PairFirstAppliedBrand<String>, _, _>(m, |x| {
1939 bind::<PairFirstAppliedBrand<String>, _, _>(f(x), g)
1940 })
1941 }
1942
1943 #[test]
1947 fn par_fold_map_pair_with_first() {
1948 let x = Pair("a".to_string(), 1);
1949 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1950 assert_eq!(
1951 par_fold_map::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, x),
1952 "1".to_string()
1953 );
1954 }
1955
1956 #[test]
1958 fn par_fold_right_pair_with_first() {
1959 let x = Pair("a".to_string(), 1);
1960 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1961 assert_eq!(par_fold_right::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, 10, x), 11);
1962 }
1963
1964 #[test]
1968 fn par_fold_map_pair_with_second() {
1969 let x = Pair(1, "a".to_string());
1970 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1971 assert_eq!(
1972 par_fold_map::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, x),
1973 "1".to_string()
1974 );
1975 }
1976
1977 #[test]
1979 fn par_fold_right_pair_with_second() {
1980 let x = Pair(1, "a".to_string());
1981 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1982 assert_eq!(
1983 par_fold_right::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, 10, x),
1984 11
1985 );
1986 }
1987}