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 Bifunctor,
20 CloneableFn,
21 Foldable,
22 Functor,
23 Lift,
24 Monoid,
25 ParFoldable,
26 Pointed,
27 Semiapplicative,
28 Semigroup,
29 Semimonad,
30 SendCloneableFn,
31 Traversable,
32 },
33 impl_kind,
34 kinds::*,
35 },
36 fp_macros::*,
37 };
38
39 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
54 #[document_fields("The first value.", "The second value.")]
56 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
59 pub struct Pair<First, Second>(pub First, pub Second);
60
61 impl_kind! {
62 for PairBrand {
63 type Of<First,Second> = Pair<First, Second>;
64 }
65 }
66
67 impl_kind! {
68 for PairBrand {
69 type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
70 }
71 }
72
73 impl Bifunctor for PairBrand {
74 #[document_signature]
78 #[document_type_parameters(
80 "The lifetime of the values.",
81 "The type of the first value.",
82 "The type of the mapped first value.",
83 "The type of the second value.",
84 "The type of the mapped second value."
85 )]
86 #[document_parameters(
88 "The function to apply to the first value.",
89 "The function to apply to the second value.",
90 "The pair to map over."
91 )]
92 #[document_returns("A new pair containing the mapped values.")]
94 #[document_examples]
95 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
108 f: impl Fn(A) -> B + 'a,
109 g: impl Fn(C) -> D + 'a,
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 let Pair(a, c) = p;
113 Pair(f(a), g(c))
114 }
115 }
116
117 impl_kind! {
120 #[document_type_parameters("The type of the first value in the pair.")]
121 impl<First: 'static> for PairFirstAppliedBrand<First> {
122 type Of<'a, A: 'a>: 'a = Pair<First, A>;
123 }
124 }
125
126 #[document_type_parameters("The type of the first value in the pair.")]
127 impl<First: 'static> Functor for PairFirstAppliedBrand<First> {
128 #[document_signature]
132 #[document_type_parameters(
134 "The lifetime of the values.",
135 "The type of the second value.",
136 "The type of the result of applying the function."
137 )]
138 #[document_parameters(
140 "The function to apply to the second value.",
141 "The pair to map over."
142 )]
143 #[document_returns(
145 "A new pair containing the result of applying the function to the second value."
146 )]
147 #[document_examples]
148 fn map<'a, A: 'a, B: 'a>(
159 func: impl Fn(A) -> B + 'a,
160 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
161 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
162 Pair(fa.0, func(fa.1))
163 }
164 }
165
166 #[document_type_parameters("The type of the first value in the pair.")]
167 impl<First: Clone + 'static> Lift for PairFirstAppliedBrand<First>
168 where
169 First: Semigroup,
170 {
171 #[document_signature]
175 #[document_type_parameters(
177 "The lifetime of the values.",
178 "The type of the first second value.",
179 "The type of the second second value.",
180 "The type of the result second value."
181 )]
182 #[document_parameters(
184 "The binary function to apply to the second values.",
185 "The first pair.",
186 "The second pair."
187 )]
188 #[document_returns(
190 "A new pair where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
191 )]
192 #[document_examples]
193 fn lift2<'a, A, B, C>(
211 func: impl Fn(A, B) -> C + 'a,
212 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
213 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
214 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
215 where
216 A: Clone + 'a,
217 B: Clone + 'a,
218 C: 'a, {
219 Pair(Semigroup::append(fa.0, fb.0), func(fa.1, fb.1))
220 }
221 }
222
223 #[document_type_parameters("The type of the first value in the pair.")]
224 impl<First: Clone + 'static> Pointed for PairFirstAppliedBrand<First>
225 where
226 First: Monoid,
227 {
228 #[document_signature]
232 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
234 #[document_parameters("The value to wrap.")]
236 #[document_returns("A pair containing the empty value of the first type and `a`.")]
238 #[document_examples]
240 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
251 Pair(Monoid::empty(), a)
252 }
253 }
254
255 #[document_type_parameters("The type of the first value in the pair.")]
256 impl<First: Clone + Semigroup + 'static> ApplyFirst for PairFirstAppliedBrand<First> {}
257
258 #[document_type_parameters("The type of the first value in the pair.")]
259 impl<First: Clone + Semigroup + 'static> ApplySecond for PairFirstAppliedBrand<First> {}
260
261 #[document_type_parameters("The type of the first value in the pair.")]
262 impl<First: Clone + 'static> Semiapplicative for PairFirstAppliedBrand<First>
263 where
264 First: Semigroup,
265 {
266 #[document_signature]
270 #[document_type_parameters(
272 "The lifetime of the values.",
273 "The brand of the cloneable function wrapper.",
274 "The type of the input value.",
275 "The type of the output value."
276 )]
277 #[document_parameters(
279 "The pair containing the function.",
280 "The pair containing the value."
281 )]
282 #[document_returns(
284 "A new pair where the first values are combined and the function is applied to the second value."
285 )]
286 #[document_examples]
287 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
302 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
303 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
304 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
305 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
306 }
307 }
308
309 #[document_type_parameters("The type of the first value in the pair.")]
310 impl<First: Clone + 'static> Semimonad for PairFirstAppliedBrand<First>
311 where
312 First: Semigroup,
313 {
314 #[document_signature]
318 #[document_type_parameters(
320 "The lifetime of the values.",
321 "The type of the result of the first computation.",
322 "The type of the result of the second computation."
323 )]
324 #[document_parameters("The first pair.", "The function to apply to the second value.")]
326 #[document_returns("A new pair where the first values are combined.")]
328 #[document_examples]
330 fn bind<'a, A: 'a, B: 'a>(
347 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
348 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
349 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
350 let Pair(first, second) = ma;
351 let Pair(next_first, next_second) = func(second);
352 Pair(Semigroup::append(first, next_first), next_second)
353 }
354 }
355
356 #[document_type_parameters("The type of the first value in the pair.")]
357 impl<First: 'static> Foldable for PairFirstAppliedBrand<First> {
358 #[document_signature]
362 #[document_type_parameters(
364 "The lifetime of the values.",
365 "The brand of the cloneable function to use.",
366 "The type of the elements in the structure.",
367 "The type of the accumulator."
368 )]
369 #[document_parameters("The folding function.", "The initial value.", "The pair to fold.")]
371 #[document_returns("`func(a, initial)`.")]
373 #[document_examples]
375 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
389 func: impl Fn(A, B) -> B + 'a,
390 initial: B,
391 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
392 ) -> B
393 where
394 FnBrand: CloneableFn + 'a, {
395 func(fa.1, initial)
396 }
397
398 #[document_signature]
402 #[document_type_parameters(
404 "The lifetime of the values.",
405 "The brand of the cloneable function to use.",
406 "The type of the elements in the structure.",
407 "The type of the accumulator."
408 )]
409 #[document_parameters(
411 "The function to apply to the accumulator and each element.",
412 "The initial value of the accumulator.",
413 "The identity to fold."
414 )]
415 #[document_returns("`func(initial, a)`.")]
417 #[document_examples]
418 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
432 func: impl Fn(B, A) -> B + 'a,
433 initial: B,
434 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
435 ) -> B
436 where
437 FnBrand: CloneableFn + 'a, {
438 func(initial, fa.1)
439 }
440
441 #[document_signature]
445 #[document_type_parameters(
447 "The lifetime of the values.",
448 "The brand of the cloneable function to use.",
449 "The type of the elements in the structure.",
450 "The type of the monoid."
451 )]
452 #[document_parameters("The mapping function.", "The pair to fold.")]
454 #[document_returns("`func(a)`.")]
456 #[document_examples]
458 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
472 func: impl Fn(A) -> M + 'a,
473 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
474 ) -> M
475 where
476 M: Monoid + 'a,
477 FnBrand: CloneableFn + 'a, {
478 func(fa.1)
479 }
480 }
481
482 #[document_type_parameters("The type of the first value in the pair.")]
483 impl<First: Clone + 'static> Traversable for PairFirstAppliedBrand<First> {
484 #[document_signature]
488 #[document_type_parameters(
490 "The lifetime of the values.",
491 "The type of the elements in the traversable structure.",
492 "The type of the elements in the resulting traversable structure.",
493 "The applicative context."
494 )]
495 #[document_parameters(
497 "The function to apply to each element, returning a value in an applicative context.",
498 "The pair to traverse."
499 )]
500 #[document_returns("The pair wrapped in the applicative context.")]
502 #[document_examples]
503 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
517 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
518 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
519 ) -> 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>)>)
520 where
521 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
522 let Pair(first, second) = ta;
523 F::map(move |b| Pair(first.clone(), b), func(second))
524 }
525
526 #[document_signature]
530 #[document_type_parameters(
532 "The lifetime of the values.",
533 "The type of the elements in the traversable structure.",
534 "The applicative context."
535 )]
536 #[document_parameters("The pair containing the applicative value.")]
538 #[document_returns("The pair wrapped in the applicative context.")]
540 #[document_examples]
542 fn sequence<'a, A: 'a + Clone, F: Applicative>(
556 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>)>)
557 ) -> 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>)>)
558 where
559 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
560 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
561 let Pair(first, second) = ta;
562 F::map(move |a| Pair(first.clone(), a), second)
563 }
564 }
565
566 #[document_type_parameters("The type of the first value in the pair.")]
567 impl<First: 'static> ParFoldable for PairFirstAppliedBrand<First> {
568 #[document_signature]
572 #[document_type_parameters(
574 "The lifetime of the values.",
575 "The brand of the cloneable function wrapper.",
576 "The element type.",
577 "The monoid type."
578 )]
579 #[document_parameters(
581 "The thread-safe function to map each element to a monoid.",
582 "The pair to fold."
583 )]
584 #[document_returns("The combined monoid value.")]
586 #[document_examples]
587 fn par_fold_map<'a, FnBrand, A, M>(
603 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
604 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
605 ) -> M
606 where
607 FnBrand: 'a + SendCloneableFn,
608 A: 'a + Clone + Send + Sync,
609 M: Monoid + Send + Sync + 'a, {
610 func(fa.1)
611 }
612
613 #[document_signature]
617 #[document_type_parameters(
619 "The lifetime of the values.",
620 "The brand of the cloneable function wrapper.",
621 "The element type.",
622 "The accumulator type."
623 )]
624 #[document_parameters(
626 "The thread-safe function to apply to each element and the accumulator.",
627 "The initial value.",
628 "The pair to fold."
629 )]
630 #[document_returns("The final accumulator value.")]
632 #[document_examples]
633 fn par_fold_right<'a, FnBrand, A, B>(
646 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
647 initial: B,
648 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
649 ) -> B
650 where
651 FnBrand: 'a + SendCloneableFn,
652 A: 'a + Clone + Send + Sync,
653 B: Send + Sync + 'a, {
654 func((fa.1, initial))
655 }
656 }
657 impl_kind! {
660 #[document_type_parameters("The type of the second value in the pair.")]
661 impl<Second: 'static> for PairSecondAppliedBrand<Second> {
662 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
663 }
664 }
665
666 #[document_type_parameters("The type of the second value in the pair.")]
667 impl<Second: 'static> Functor for PairSecondAppliedBrand<Second> {
668 #[document_signature]
672 #[document_type_parameters(
674 "The lifetime of the values.",
675 "The type of the first value.",
676 "The type of the result of applying the function."
677 )]
678 #[document_parameters("The function to apply to the first value.", "The pair to map over.")]
680 #[document_returns(
682 "A new pair containing the result of applying the function to the first value."
683 )]
684 #[document_examples]
686 fn map<'a, A: 'a, B: 'a>(
697 func: impl Fn(A) -> B + 'a,
698 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
699 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
700 Pair(func(fa.0), fa.1)
701 }
702 }
703
704 #[document_type_parameters("The type of the second value in the pair.")]
705 impl<Second: Clone + 'static> Lift for PairSecondAppliedBrand<Second>
706 where
707 Second: Semigroup,
708 {
709 #[document_signature]
713 #[document_type_parameters(
715 "The lifetime of the values.",
716 "The type of the first first value.",
717 "The type of the second first value.",
718 "The type of the result first value."
719 )]
720 #[document_parameters(
722 "The binary function to apply to the first values.",
723 "The first pair.",
724 "The second pair."
725 )]
726 #[document_returns(
728 "A new pair where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
729 )]
730 #[document_examples]
731 fn lift2<'a, A, B, C>(
749 func: impl Fn(A, B) -> C + 'a,
750 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
751 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
752 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
753 where
754 A: Clone + 'a,
755 B: Clone + 'a,
756 C: 'a, {
757 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
758 }
759 }
760
761 #[document_type_parameters("The type of the second value in the pair.")]
762 impl<Second: Clone + 'static> Pointed for PairSecondAppliedBrand<Second>
763 where
764 Second: Monoid,
765 {
766 #[document_signature]
770 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
772 #[document_parameters("The value to wrap.")]
774 #[document_returns("A pair containing `a` and the empty value of the second type.")]
776 #[document_examples]
778 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
789 Pair(a, Monoid::empty())
790 }
791 }
792
793 #[document_type_parameters("The type of the second value in the pair.")]
794 impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairSecondAppliedBrand<Second> {}
795
796 #[document_type_parameters("The type of the second value in the pair.")]
797 impl<Second: Clone + Semigroup + 'static> ApplySecond for PairSecondAppliedBrand<Second> {}
798
799 #[document_type_parameters("The type of the second value in the pair.")]
800 impl<Second: Clone + 'static> Semiapplicative for PairSecondAppliedBrand<Second>
801 where
802 Second: Semigroup,
803 {
804 #[document_signature]
808 #[document_type_parameters(
810 "The lifetime of the values.",
811 "The brand of the cloneable function wrapper.",
812 "The type of the input value.",
813 "The type of the output value."
814 )]
815 #[document_parameters(
817 "The pair containing the function (in Err).",
818 "The pair containing the value (in Err)."
819 )]
820 #[document_returns(
822 "`Err(f(a))` if both are `Err`, otherwise the first success encountered."
823 )]
824 #[document_examples]
825 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
840 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
841 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
842 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
843 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
844 }
845 }
846
847 #[document_type_parameters("The type of the second value in the pair.")]
848 impl<Second: Clone + 'static> Semimonad for PairSecondAppliedBrand<Second>
849 where
850 Second: Semigroup,
851 {
852 #[document_signature]
856 #[document_type_parameters(
858 "The lifetime of the values.",
859 "The type of the result of the first computation.",
860 "The type of the result of the second computation."
861 )]
862 #[document_parameters("The first result.", "The function to apply to the error value.")]
864 #[document_returns(
866 "The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
867 )]
868 #[document_examples]
870 fn bind<'a, A: 'a, B: 'a>(
887 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
888 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
889 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
890 let Pair(first, second) = ma;
891 let Pair(next_first, next_second) = func(first);
892 Pair(next_first, Semigroup::append(second, next_second))
893 }
894 }
895
896 #[document_type_parameters("The type of the second value in the pair.")]
897 impl<Second: 'static> Foldable for PairSecondAppliedBrand<Second> {
898 #[document_signature]
902 #[document_type_parameters(
904 "The lifetime of the values.",
905 "The brand of the cloneable function to use.",
906 "The type of the elements in the structure.",
907 "The type of the accumulator."
908 )]
909 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
911 #[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
913 #[document_examples]
915 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
929 func: impl Fn(A, B) -> B + 'a,
930 initial: B,
931 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
932 ) -> B
933 where
934 FnBrand: CloneableFn + 'a, {
935 func(fa.0, initial)
936 }
937
938 #[document_signature]
942 #[document_type_parameters(
944 "The lifetime of the values.",
945 "The brand of the cloneable function to use.",
946 "The type of the elements in the structure.",
947 "The type of the accumulator."
948 )]
949 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
951 #[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
953 #[document_examples]
955 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
969 func: impl Fn(B, A) -> B + 'a,
970 initial: B,
971 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
972 ) -> B
973 where
974 FnBrand: CloneableFn + 'a, {
975 func(initial, fa.0)
976 }
977
978 #[document_signature]
982 #[document_type_parameters(
984 "The lifetime of the values.",
985 "The brand of the cloneable function to use.",
986 "The type of the elements in the structure.",
987 "The type of the monoid."
988 )]
989 #[document_parameters("The mapping function.", "The result to fold.")]
991 #[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
993 #[document_examples]
995 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1012 func: impl Fn(A) -> M + 'a,
1013 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1014 ) -> M
1015 where
1016 M: Monoid + 'a,
1017 FnBrand: CloneableFn + 'a, {
1018 func(fa.0)
1019 }
1020 }
1021
1022 #[document_type_parameters("The type of the second value in the pair.")]
1023 impl<Second: Clone + 'static> Traversable for PairSecondAppliedBrand<Second> {
1024 #[document_signature]
1028 #[document_type_parameters(
1030 "The lifetime of the values.",
1031 "The type of the elements in the traversable structure.",
1032 "The type of the elements in the resulting traversable structure.",
1033 "The applicative context."
1034 )]
1035 #[document_parameters("The function to apply.", "The result to traverse.")]
1037 #[document_returns("The result wrapped in the applicative context.")]
1039 #[document_examples]
1041 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1055 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1056 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1057 ) -> 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>)>)
1058 where
1059 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1060 let Pair(first, second) = ta;
1061 F::map(move |b| Pair(b, second.clone()), func(first))
1062 }
1063
1064 #[document_signature]
1068 #[document_type_parameters(
1070 "The lifetime of the values.",
1071 "The type of the elements in the traversable structure.",
1072 "The applicative context."
1073 )]
1074 #[document_parameters("The result containing the applicative value.")]
1076 #[document_returns("The result wrapped in the applicative context.")]
1078 #[document_examples]
1080 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1094 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>)>)
1095 ) -> 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>)>)
1096 where
1097 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1098 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1099 let Pair(first, second) = ta;
1100 F::map(move |a| Pair(a, second.clone()), first)
1101 }
1102 }
1103
1104 #[document_type_parameters("The type of the second value in the pair.")]
1105 impl<Second: 'static> ParFoldable for PairSecondAppliedBrand<Second> {
1106 #[document_signature]
1110 #[document_type_parameters(
1112 "The lifetime of the values.",
1113 "The brand of the cloneable function wrapper.",
1114 "The element type.",
1115 "The monoid type."
1116 )]
1117 #[document_parameters(
1119 "The thread-safe function to map each element to a monoid.",
1120 "The pair to fold."
1121 )]
1122 #[document_returns("The combined monoid value.")]
1124 #[document_examples]
1125 fn par_fold_map<'a, FnBrand, A, M>(
1141 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1142 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1143 ) -> M
1144 where
1145 FnBrand: 'a + SendCloneableFn,
1146 A: 'a + Clone + Send + Sync,
1147 M: Monoid + Send + Sync + 'a, {
1148 func(fa.0)
1149 }
1150
1151 #[document_signature]
1155 #[document_type_parameters(
1157 "The lifetime of the values.",
1158 "The brand of the cloneable function wrapper.",
1159 "The element type.",
1160 "The accumulator type."
1161 )]
1162 #[document_parameters(
1164 "The thread-safe function to apply to each element and the accumulator.",
1165 "The initial value.",
1166 "The pair to fold."
1167 )]
1168 #[document_returns("The final accumulator value.")]
1170 #[document_examples]
1171 fn par_fold_right<'a, FnBrand, A, B>(
1184 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1185 initial: B,
1186 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1187 ) -> B
1188 where
1189 FnBrand: 'a + SendCloneableFn,
1190 A: 'a + Clone + Send + Sync,
1191 B: Send + Sync + 'a, {
1192 func((fa.0, initial))
1193 }
1194 }
1195}
1196pub use inner::*;
1197
1198#[cfg(test)]
1199mod tests {
1200 use {
1201 super::inner::*,
1202 crate::{
1203 brands::*,
1204 classes::{
1205 CloneableFn,
1206 bifunctor::*,
1207 },
1208 functions::*,
1209 },
1210 quickcheck_macros::quickcheck,
1211 };
1212
1213 #[test]
1217 fn test_bimap() {
1218 let x = Pair(1, 5);
1219 assert_eq!(bimap::<PairBrand, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1220 }
1221
1222 #[quickcheck]
1226 fn bifunctor_identity(
1227 first: String,
1228 second: i32,
1229 ) -> bool {
1230 let x = Pair(first, second);
1231 bimap::<PairBrand, _, _, _, _>(identity, identity, x.clone()) == x
1232 }
1233
1234 #[quickcheck]
1236 fn bifunctor_composition(
1237 first: i32,
1238 second: i32,
1239 ) -> bool {
1240 let x = Pair(first, second);
1241 let f = |x: i32| x.wrapping_add(1);
1242 let g = |x: i32| x.wrapping_mul(2);
1243 let h = |x: i32| x.wrapping_sub(1);
1244 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1245
1246 bimap::<PairBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1247 == bimap::<PairBrand, _, _, _, _>(f, h, bimap::<PairBrand, _, _, _, _>(g, i, x))
1248 }
1249
1250 #[quickcheck]
1254 fn functor_identity(
1255 first: String,
1256 second: i32,
1257 ) -> bool {
1258 let x = Pair(first, second);
1259 map::<PairFirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1260 }
1261
1262 #[quickcheck]
1264 fn functor_composition(
1265 first: String,
1266 second: i32,
1267 ) -> bool {
1268 let x = Pair(first, second);
1269 let f = |x: i32| x.wrapping_add(1);
1270 let g = |x: i32| x.wrapping_mul(2);
1271 map::<PairFirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1272 == map::<PairFirstAppliedBrand<String>, _, _>(
1273 f,
1274 map::<PairFirstAppliedBrand<String>, _, _>(g, x),
1275 )
1276 }
1277
1278 #[quickcheck]
1282 fn applicative_identity(
1283 first: String,
1284 second: i32,
1285 ) -> bool {
1286 let v = Pair(first, second);
1287 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1288 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1289 v.clone(),
1290 ) == v
1291 }
1292
1293 #[quickcheck]
1295 fn applicative_homomorphism(x: i32) -> bool {
1296 let f = |x: i32| x.wrapping_mul(2);
1297 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1298 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1299 pure::<PairFirstAppliedBrand<String>, _>(x),
1300 ) == pure::<PairFirstAppliedBrand<String>, _>(f(x))
1301 }
1302
1303 #[quickcheck]
1305 fn applicative_composition(
1306 w_first: String,
1307 w_second: i32,
1308 u_seed: i32,
1309 v_seed: i32,
1310 ) -> bool {
1311 let w = Pair(w_first, w_second);
1312
1313 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1314 let u = pure::<PairFirstAppliedBrand<String>, _>(u_fn);
1315
1316 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1317 let v = pure::<PairFirstAppliedBrand<String>, _>(v_fn);
1318
1319 let vw = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1321 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u.clone(), vw);
1322
1323 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1325 let f = f.clone();
1326 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1327 let f = f.clone();
1328 let g = g.clone();
1329 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1330 })
1331 });
1332
1333 let pure_compose = pure::<PairFirstAppliedBrand<String>, _>(compose_fn);
1334 let u_applied = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(pure_compose, u);
1335 let uv = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u_applied, v);
1336 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(uv, w);
1337
1338 lhs == rhs
1339 }
1340
1341 #[quickcheck]
1343 fn applicative_interchange(
1344 y: i32,
1345 u_seed: i32,
1346 ) -> bool {
1347 let f = move |x: i32| x.wrapping_mul(u_seed);
1349 let u = pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1350
1351 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1352 u.clone(),
1353 pure::<PairFirstAppliedBrand<String>, _>(y),
1354 );
1355
1356 let rhs_fn =
1357 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1358 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1359 pure::<PairFirstAppliedBrand<String>, _>(rhs_fn),
1360 u,
1361 );
1362
1363 lhs == rhs
1364 }
1365
1366 #[quickcheck]
1370 fn monad_left_identity(a: i32) -> bool {
1371 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1372 bind::<PairFirstAppliedBrand<String>, _, _>(pure::<PairFirstAppliedBrand<String>, _>(a), f)
1373 == f(a)
1374 }
1375
1376 #[quickcheck]
1378 fn monad_right_identity(
1379 first: String,
1380 second: i32,
1381 ) -> bool {
1382 let m = Pair(first, second);
1383 bind::<PairFirstAppliedBrand<String>, _, _>(
1384 m.clone(),
1385 pure::<PairFirstAppliedBrand<String>, _>,
1386 ) == m
1387 }
1388
1389 #[quickcheck]
1391 fn monad_associativity(
1392 first: String,
1393 second: i32,
1394 ) -> bool {
1395 let m = Pair(first, second);
1396 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1397 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1398 bind::<PairFirstAppliedBrand<String>, _, _>(
1399 bind::<PairFirstAppliedBrand<String>, _, _>(m.clone(), f),
1400 g,
1401 ) == bind::<PairFirstAppliedBrand<String>, _, _>(m, |x| {
1402 bind::<PairFirstAppliedBrand<String>, _, _>(f(x), g)
1403 })
1404 }
1405
1406 #[test]
1410 fn par_fold_map_pair_with_first() {
1411 let x = Pair("a".to_string(), 1);
1412 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1413 assert_eq!(
1414 par_fold_map::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, x),
1415 "1".to_string()
1416 );
1417 }
1418
1419 #[test]
1421 fn par_fold_right_pair_with_first() {
1422 let x = Pair("a".to_string(), 1);
1423 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1424 assert_eq!(par_fold_right::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, 10, x), 11);
1425 }
1426
1427 #[test]
1431 fn par_fold_map_pair_with_second() {
1432 let x = Pair(1, "a".to_string());
1433 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1434 assert_eq!(
1435 par_fold_map::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, x),
1436 "1".to_string()
1437 );
1438 }
1439
1440 #[test]
1442 fn par_fold_right_pair_with_second() {
1443 let x = Pair(1, "a".to_string());
1444 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1445 assert_eq!(
1446 par_fold_right::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, 10, x),
1447 11
1448 );
1449 }
1450}