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 dispatch::Ref,
17 impl_kind,
18 kinds::*,
19 },
20 core::ops::ControlFlow,
21 fp_macros::*,
22 };
23
24 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
39 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
42 pub struct Pair<First, Second>(
43 pub First,
45 pub Second,
47 );
48
49 impl_kind! {
50 for PairBrand {
51 type Of<First,Second> = Pair<First, Second>;
52 }
53 }
54
55 impl_kind! {
56 for PairBrand {
57 type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
58 }
59 }
60
61 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
62 #[document_parameters("The pair instance.")]
63 impl<First, Second> Pair<First, Second> {
64 #[document_signature]
68 #[document_type_parameters(
70 "The type of the mapped first value.",
71 "The type of the mapped second value."
72 )]
73 #[document_parameters(
75 "The function to apply to the first value.",
76 "The function to apply to the second value."
77 )]
78 #[document_returns("A new pair containing the mapped values.")]
80 #[document_examples]
82 pub fn bimap<B, D>(
90 self,
91 f: impl FnOnce(First) -> B,
92 g: impl FnOnce(Second) -> D,
93 ) -> Pair<B, D> {
94 Pair(f(self.0), g(self.1))
95 }
96
97 #[document_signature]
101 #[document_type_parameters("The type of the mapped first value.")]
103 #[document_parameters("The function to apply to the first value.")]
105 #[document_returns("A new pair with the transformed first value.")]
107 #[document_examples]
109 pub fn map_first<B>(
117 self,
118 f: impl FnOnce(First) -> B,
119 ) -> Pair<B, Second> {
120 Pair(f(self.0), self.1)
121 }
122
123 #[document_signature]
127 #[document_type_parameters("The type of the mapped second value.")]
129 #[document_parameters("The function to apply to the second value.")]
131 #[document_returns("A new pair with the transformed second value.")]
133 #[document_examples]
135 pub fn map_second<D>(
143 self,
144 g: impl FnOnce(Second) -> D,
145 ) -> Pair<First, D> {
146 Pair(self.0, g(self.1))
147 }
148
149 #[document_signature]
154 #[document_type_parameters("The result type.")]
156 #[document_parameters(
158 "The function to apply to the first value.",
159 "The function to apply to the second value.",
160 "The function to combine the results."
161 )]
162 #[document_returns("The combined result.")]
164 #[document_examples]
166 pub fn fold<C>(
175 self,
176 f: impl FnOnce(First) -> C,
177 g: impl FnOnce(Second) -> C,
178 combine: impl FnOnce(C, C) -> C,
179 ) -> C {
180 combine(f(self.0), g(self.1))
181 }
182
183 #[document_signature]
187 #[document_type_parameters("The accumulator type.")]
189 #[document_parameters(
191 "The step function for the first value.",
192 "The step function for the second value.",
193 "The initial accumulator."
194 )]
195 #[document_returns("The result of folding: `f(first, g(second, z))`.")]
197 #[document_examples]
199 pub fn bi_fold_right<C>(
207 self,
208 f: impl FnOnce(First, C) -> C,
209 g: impl FnOnce(Second, C) -> C,
210 z: C,
211 ) -> C {
212 f(self.0, g(self.1, z))
213 }
214
215 #[document_signature]
219 #[document_type_parameters("The accumulator type.")]
221 #[document_parameters(
223 "The step function for the first value.",
224 "The step function for the second value.",
225 "The initial accumulator."
226 )]
227 #[document_returns("The result of folding: `g(f(z, first), second)`.")]
229 #[document_examples]
231 pub fn bi_fold_left<C>(
239 self,
240 f: impl FnOnce(C, First) -> C,
241 g: impl FnOnce(C, Second) -> C,
242 z: C,
243 ) -> C {
244 g(f(z, self.0), self.1)
245 }
246
247 #[document_signature]
251 #[document_type_parameters("The monoid type.")]
253 #[document_parameters(
255 "The function mapping the first value to the monoid.",
256 "The function mapping the second value to the monoid."
257 )]
258 #[document_returns("The combined monoid value.")]
260 #[document_examples]
262 pub fn bi_fold_map<M: Semigroup>(
270 self,
271 f: impl FnOnce(First) -> M,
272 g: impl FnOnce(Second) -> M,
273 ) -> M {
274 Semigroup::append(f(self.0), g(self.1))
275 }
276 }
277
278 #[document_type_parameters(
279 "The lifetime of the values.",
280 "The type of the first value.",
281 "The type of the second value."
282 )]
283 #[document_parameters("The pair instance.")]
284 impl<'a, First: 'a, Second: 'a> Pair<First, Second> {
285 #[document_signature]
289 #[document_type_parameters(
291 "The output type for the first value.",
292 "The output type for the second value.",
293 "The applicative context."
294 )]
295 #[document_parameters(
297 "The function for the first value.",
298 "The function for the second value."
299 )]
300 #[document_returns("A pair of the transformed values wrapped in the applicative context.")]
302 #[document_examples]
304 pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
316 self,
317 f: impl Fn(First) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
318 g: impl Fn(Second) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
319 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Pair<C, D>>)
320 where
321 Pair<C, D>: Clone, {
322 F::lift2(|c, d| Pair(c, d), f(self.0), g(self.1))
323 }
324 }
325
326 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
327 #[document_parameters("The pair instance.")]
328 impl<First: Semigroup, Second> Pair<First, Second> {
329 #[document_signature]
334 #[document_type_parameters("The type of the new second value.")]
336 #[document_parameters("The function to apply to the second value.")]
338 #[document_returns(
340 "A new pair where the first values are combined and the second value is transformed."
341 )]
342 #[document_examples]
344 pub fn bind<C>(
354 self,
355 f: impl FnOnce(Second) -> Pair<First, C>,
356 ) -> Pair<First, C> {
357 let Pair(first, second) = self;
358 let Pair(next_first, next_second) = f(second);
359 Pair(Semigroup::append(first, next_first), next_second)
360 }
361 }
362
363 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
364 #[document_parameters("The pair instance.")]
365 impl<First, Second: Semigroup> Pair<First, Second> {
366 #[document_signature]
371 #[document_type_parameters("The type of the new first value.")]
373 #[document_parameters("The function to apply to the first value.")]
375 #[document_returns(
377 "A new pair where the first value is transformed and the second values are combined."
378 )]
379 #[document_examples]
381 pub fn bind_first<C>(
391 self,
392 f: impl FnOnce(First) -> Pair<C, Second>,
393 ) -> Pair<C, Second> {
394 let Pair(first, second) = self;
395 let Pair(next_first, next_second) = f(first);
396 Pair(next_first, Semigroup::append(second, next_second))
397 }
398 }
399
400 impl Bifunctor for PairBrand {
401 #[document_signature]
405 #[document_type_parameters(
407 "The lifetime of the values.",
408 "The type of the first value.",
409 "The type of the mapped first value.",
410 "The type of the second value.",
411 "The type of the mapped second value."
412 )]
413 #[document_parameters(
415 "The function to apply to the first value.",
416 "The function to apply to the second value.",
417 "The pair to map over."
418 )]
419 #[document_returns("A new pair containing the mapped values.")]
421 #[document_examples]
422 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
437 f: impl Fn(A) -> B + 'a,
438 g: impl Fn(C) -> D + 'a,
439 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
440 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
441 p.bimap(f, g)
442 }
443 }
444
445 impl RefBifunctor for PairBrand {
446 #[document_signature]
452 #[document_type_parameters(
454 "The lifetime of the values.",
455 "The type of the first value.",
456 "The type of the mapped first value.",
457 "The type of the second value.",
458 "The type of the mapped second value."
459 )]
460 #[document_parameters(
462 "The function to apply to a reference of the first value.",
463 "The function to apply to a reference of the second value.",
464 "The pair to map over by reference."
465 )]
466 #[document_returns("A new pair containing the mapped values.")]
468 #[document_examples]
469 fn ref_bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
481 f: impl Fn(&A) -> B + 'a,
482 g: impl Fn(&C) -> D + 'a,
483 p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
484 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
485 Pair(f(&p.0), g(&p.1))
486 }
487 }
488
489 impl RefBifoldable for PairBrand {
490 #[document_signature]
494 #[document_type_parameters(
496 "The lifetime of the values.",
497 "The brand of the cloneable function to use.",
498 "The type of the first value.",
499 "The type of the second value.",
500 "The accumulator type."
501 )]
502 #[document_parameters(
504 "The step function for a reference to the first value.",
505 "The step function for a reference to the second value.",
506 "The initial accumulator.",
507 "The pair to fold by reference."
508 )]
509 #[document_returns("`f(&a, g(&b, z))`.")]
511 #[document_examples]
512 fn ref_bi_fold_right<'a, FnBrand: LiftFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
532 f: impl Fn(&A, C) -> C + 'a,
533 g: impl Fn(&B, C) -> C + 'a,
534 z: C,
535 p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
536 ) -> C {
537 f(&p.0, g(&p.1, z))
538 }
539 }
540
541 impl RefBitraversable for PairBrand {
542 #[document_signature]
547 #[document_type_parameters(
549 "The lifetime of the values.",
550 "The brand of the cloneable function wrapper.",
551 "The type of the first value.",
552 "The type of the second value.",
553 "The output type for the first value.",
554 "The output type for the second value.",
555 "The applicative context."
556 )]
557 #[document_parameters(
559 "The function applied to a reference to the first value.",
560 "The function applied to a reference to the second value.",
561 "The pair to traverse by reference."
562 )]
563 #[document_returns("`lift2(Pair, f(&a), g(&b))`.")]
565 #[document_examples]
566 fn ref_bi_traverse<
585 'a,
586 FnBrand,
587 A: 'a + Clone,
588 B: 'a + Clone,
589 C: 'a + Clone,
590 D: 'a + Clone,
591 F: Applicative,
592 >(
593 f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
594 g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
595 p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
596 ) -> 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>)>)
597 where
598 FnBrand: LiftFn + 'a,
599 Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>): Clone,
600 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
601 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone, {
602 F::lift2(|c, d| Pair(c, d), f(&p.0), g(&p.1))
603 }
604 }
605
606 impl Bifoldable for PairBrand {
607 #[document_signature]
611 #[document_type_parameters(
613 "The lifetime of the values.",
614 "The brand of the cloneable function to use.",
615 "The type of the first value.",
616 "The type of the second value.",
617 "The accumulator type."
618 )]
619 #[document_parameters(
621 "The step function for the first value.",
622 "The step function for the second value.",
623 "The initial accumulator.",
624 "The pair to fold."
625 )]
626 #[document_returns("`f(a, g(b, z))`.")]
628 #[document_examples]
629 fn bi_fold_right<'a, FnBrand: CloneFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
648 f: impl Fn(A, C) -> C + 'a,
649 g: impl Fn(B, C) -> C + 'a,
650 z: C,
651 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
652 ) -> C {
653 p.bi_fold_right(f, g, z)
654 }
655
656 #[document_signature]
660 #[document_type_parameters(
662 "The lifetime of the values.",
663 "The brand of the cloneable function to use.",
664 "The type of the first value.",
665 "The type of the second value.",
666 "The accumulator type."
667 )]
668 #[document_parameters(
670 "The step function for the first value.",
671 "The step function for the second value.",
672 "The initial accumulator.",
673 "The pair to fold."
674 )]
675 #[document_returns("`g(f(z, a), b)`.")]
677 #[document_examples]
678 fn bi_fold_left<'a, FnBrand: CloneFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
697 f: impl Fn(C, A) -> C + 'a,
698 g: impl Fn(C, B) -> C + 'a,
699 z: C,
700 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
701 ) -> C {
702 p.bi_fold_left(f, g, z)
703 }
704
705 #[document_signature]
709 #[document_type_parameters(
711 "The lifetime of the values.",
712 "The brand of the cloneable function to use.",
713 "The type of the first value.",
714 "The type of the second value.",
715 "The monoid type."
716 )]
717 #[document_parameters(
719 "The function mapping the first value to the monoid.",
720 "The function mapping the second value to the monoid.",
721 "The pair to fold."
722 )]
723 #[document_returns("`Semigroup::append(f(a), g(b))`.")]
725 #[document_examples]
726 fn bi_fold_map<'a, FnBrand: CloneFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
743 f: impl Fn(A) -> M + 'a,
744 g: impl Fn(B) -> M + 'a,
745 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
746 ) -> M
747 where
748 M: Monoid + 'a, {
749 p.bi_fold_map(f, g)
750 }
751 }
752
753 impl Bitraversable for PairBrand {
754 #[document_signature]
759 #[document_type_parameters(
761 "The lifetime of the values.",
762 "The type of the first value.",
763 "The type of the second value.",
764 "The output type for the first value.",
765 "The output type for the second value.",
766 "The applicative context."
767 )]
768 #[document_parameters(
770 "The function applied to the first value.",
771 "The function applied to the second value.",
772 "The pair to traverse."
773 )]
774 #[document_returns("`lift2(Pair, f(a), g(b))`.")]
776 #[document_examples]
777 fn bi_traverse<
795 'a,
796 A: 'a + Clone,
797 B: 'a + Clone,
798 C: 'a + Clone,
799 D: 'a + Clone,
800 F: Applicative,
801 >(
802 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
803 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
804 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
805 ) -> 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>)>)
806 {
807 p.bi_traverse::<C, D, F>(f, g)
808 }
809 }
810
811 impl_kind! {
814 #[multi_brand]
815 #[document_type_parameters("The type of the first value in the pair.")]
816 impl<First: 'static> for PairFirstAppliedBrand<First> {
817 type Of<'a, A: 'a>: 'a = Pair<First, A>;
818 }
819 }
820
821 #[document_type_parameters("The type of the first value in the pair.")]
822 impl<First: 'static> Functor for PairFirstAppliedBrand<First> {
823 #[document_signature]
827 #[document_type_parameters(
829 "The lifetime of the values.",
830 "The type of the second value.",
831 "The type of the result of applying the function."
832 )]
833 #[document_parameters(
835 "The function to apply to the second value.",
836 "The pair to map over."
837 )]
838 #[document_returns(
840 "A new pair containing the result of applying the function to the second value."
841 )]
842 #[document_examples]
843 fn map<'a, A: 'a, B: 'a>(
857 func: impl Fn(A) -> B + 'a,
858 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
859 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
860 fa.map_second(func)
861 }
862 }
863
864 #[document_type_parameters("The type of the first value in the pair.")]
865 impl<First: Clone + 'static> Lift for PairFirstAppliedBrand<First>
866 where
867 First: Semigroup,
868 {
869 #[document_signature]
873 #[document_type_parameters(
875 "The lifetime of the values.",
876 "The type of the first second value.",
877 "The type of the second second value.",
878 "The type of the result second value."
879 )]
880 #[document_parameters(
882 "The binary function to apply to the second values.",
883 "The first pair.",
884 "The second pair."
885 )]
886 #[document_returns(
888 "A new pair where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
889 )]
890 #[document_examples]
891 fn lift2<'a, A, B, C>(
909 func: impl Fn(A, B) -> C + 'a,
910 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
911 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
912 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
913 where
914 A: Clone + 'a,
915 B: Clone + 'a,
916 C: 'a, {
917 let Pair(fa_first, fa_second) = fa;
918 let Pair(fb_first, fb_second) = fb;
919 Pair(Semigroup::append(fa_first, fb_first), func(fa_second, fb_second))
920 }
921 }
922
923 #[document_type_parameters("The type of the first value in the pair.")]
924 impl<First: Clone + 'static> Pointed for PairFirstAppliedBrand<First>
925 where
926 First: Monoid,
927 {
928 #[document_signature]
932 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
934 #[document_parameters("The value to wrap.")]
936 #[document_returns("A pair containing the empty value of the first type and `a`.")]
938 #[document_examples]
940 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
951 Pair(Monoid::empty(), a)
952 }
953 }
954
955 #[document_type_parameters("The type of the first value in the pair.")]
956 impl<First: Clone + Semigroup + 'static> ApplyFirst for PairFirstAppliedBrand<First> {}
957
958 #[document_type_parameters("The type of the first value in the pair.")]
959 impl<First: Clone + Semigroup + 'static> ApplySecond for PairFirstAppliedBrand<First> {}
960
961 #[document_type_parameters("The type of the first value in the pair.")]
962 impl<First: Clone + 'static> Semiapplicative for PairFirstAppliedBrand<First>
963 where
964 First: Semigroup,
965 {
966 #[document_signature]
970 #[document_type_parameters(
972 "The lifetime of the values.",
973 "The brand of the cloneable function wrapper.",
974 "The type of the input value.",
975 "The type of the output value."
976 )]
977 #[document_parameters(
979 "The pair containing the function.",
980 "The pair containing the value."
981 )]
982 #[document_returns(
984 "A new pair where the first values are combined and the function is applied to the second value."
985 )]
986 #[document_examples]
987 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
1006 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1007 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1008 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1009 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
1010 }
1011 }
1012
1013 #[document_type_parameters("The type of the first value in the pair.")]
1014 impl<First: Clone + 'static> Semimonad for PairFirstAppliedBrand<First>
1015 where
1016 First: Semigroup,
1017 {
1018 #[document_signature]
1022 #[document_type_parameters(
1024 "The lifetime of the values.",
1025 "The type of the result of the first computation.",
1026 "The type of the result of the second computation."
1027 )]
1028 #[document_parameters("The first pair.", "The function to apply to the second value.")]
1030 #[document_returns("A new pair where the first values are combined.")]
1032 #[document_examples]
1034 fn bind<'a, A: 'a, B: 'a>(
1051 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1052 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1053 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1054 ma.bind(func)
1055 }
1056 }
1057
1058 #[document_type_parameters("The type of the first value in the pair.")]
1060 impl<First: Clone + 'static> MonadRec for PairFirstAppliedBrand<First>
1061 where
1062 First: Monoid,
1063 {
1064 #[document_signature]
1072 #[document_type_parameters(
1074 "The lifetime of the computation.",
1075 "The type of the initial value and loop state.",
1076 "The type of the result."
1077 )]
1078 #[document_parameters("The step function.", "The initial value.")]
1080 #[document_returns("A pair with the accumulated first value and the final result.")]
1082 #[document_examples]
1084 fn tail_rec_m<'a, A: 'a, B: 'a>(
1108 func: impl Fn(
1109 A,
1110 )
1111 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1112 + 'a,
1113 initial: A,
1114 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1115 let mut acc: First = Monoid::empty();
1116 let mut current = initial;
1117 loop {
1118 let Pair(first, step) = func(current);
1119 acc = Semigroup::append(acc, first);
1120 match step {
1121 ControlFlow::Continue(next) => current = next,
1122 ControlFlow::Break(b) => return Pair(acc, b),
1123 }
1124 }
1125 }
1126 }
1127
1128 #[document_type_parameters("The type of the first value in the pair.")]
1129 impl<First: 'static> Foldable for PairFirstAppliedBrand<First> {
1130 #[document_signature]
1134 #[document_type_parameters(
1136 "The lifetime of the values.",
1137 "The brand of the cloneable function to use.",
1138 "The type of the elements in the structure.",
1139 "The type of the accumulator."
1140 )]
1141 #[document_parameters("The folding function.", "The initial value.", "The pair to fold.")]
1143 #[document_returns("`func(a, initial)`.")]
1145 #[document_examples]
1147 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1165 func: impl Fn(A, B) -> B + 'a,
1166 initial: B,
1167 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1168 ) -> B
1169 where
1170 FnBrand: CloneFn + 'a, {
1171 func(fa.1, initial)
1172 }
1173
1174 #[document_signature]
1178 #[document_type_parameters(
1180 "The lifetime of the values.",
1181 "The brand of the cloneable function to use.",
1182 "The type of the elements in the structure.",
1183 "The type of the accumulator."
1184 )]
1185 #[document_parameters(
1187 "The function to apply to the accumulator and each element.",
1188 "The initial value of the accumulator.",
1189 "The identity to fold."
1190 )]
1191 #[document_returns("`func(initial, a)`.")]
1193 #[document_examples]
1194 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1212 func: impl Fn(B, A) -> B + 'a,
1213 initial: B,
1214 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1215 ) -> B
1216 where
1217 FnBrand: CloneFn + 'a, {
1218 func(initial, fa.1)
1219 }
1220
1221 #[document_signature]
1225 #[document_type_parameters(
1227 "The lifetime of the values.",
1228 "The brand of the cloneable function to use.",
1229 "The type of the elements in the structure.",
1230 "The type of the monoid."
1231 )]
1232 #[document_parameters("The mapping function.", "The pair to fold.")]
1234 #[document_returns("`func(a)`.")]
1236 #[document_examples]
1238 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1255 func: impl Fn(A) -> M + 'a,
1256 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1257 ) -> M
1258 where
1259 M: Monoid + 'a,
1260 FnBrand: CloneFn + 'a, {
1261 func(fa.1)
1262 }
1263 }
1264
1265 #[document_type_parameters("The type of the first value in the pair.")]
1266 impl<First: Clone + 'static> Traversable for PairFirstAppliedBrand<First> {
1267 #[document_signature]
1271 #[document_type_parameters(
1273 "The lifetime of the values.",
1274 "The type of the elements in the traversable structure.",
1275 "The type of the elements in the resulting traversable structure.",
1276 "The applicative context."
1277 )]
1278 #[document_parameters(
1280 "The function to apply to each element, returning a value in an applicative context.",
1281 "The pair to traverse."
1282 )]
1283 #[document_returns("The pair wrapped in the applicative context.")]
1285 #[document_examples]
1286 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1303 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1304 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1305 ) -> 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>)>)
1306 where
1307 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1308 let Pair(first, second) = ta;
1309 F::map(move |b| Pair(first.clone(), b), func(second))
1310 }
1311
1312 #[document_signature]
1316 #[document_type_parameters(
1318 "The lifetime of the values.",
1319 "The type of the elements in the traversable structure.",
1320 "The applicative context."
1321 )]
1322 #[document_parameters("The pair containing the applicative value.")]
1324 #[document_returns("The pair wrapped in the applicative context.")]
1326 #[document_examples]
1328 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1342 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>)>)
1343 ) -> 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>)>)
1344 where
1345 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1346 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1347 let Pair(first, second) = ta;
1348 F::map(move |a| Pair(first.clone(), a), second)
1349 }
1350 }
1351
1352 #[document_type_parameters("The type of the first value in the pair.")]
1355 impl<First: Clone + 'static> RefFunctor for PairFirstAppliedBrand<First> {
1356 #[document_signature]
1358 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1359 #[document_parameters("The function.", "The pair.")]
1360 #[document_returns("A new pair with the mapped second value.")]
1361 #[document_examples]
1362 fn ref_map<'a, A: 'a, B: 'a>(
1375 func: impl Fn(&A) -> B + 'a,
1376 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1377 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1378 Pair(fa.0.clone(), func(&fa.1))
1379 }
1380 }
1381
1382 #[document_type_parameters("The type of the first value in the pair.")]
1383 impl<First: Clone + 'static> RefFoldable for PairFirstAppliedBrand<First> {
1384 #[document_signature]
1386 #[document_type_parameters(
1387 "The lifetime.",
1388 "The brand.",
1389 "The element type.",
1390 "The monoid type."
1391 )]
1392 #[document_parameters("The mapping function.", "The pair.")]
1393 #[document_returns("The monoid value.")]
1394 #[document_examples]
1395 fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
1409 func: impl Fn(&A) -> M + 'a,
1410 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1411 ) -> M
1412 where
1413 FnBrand: LiftFn + 'a,
1414 M: Monoid + 'a, {
1415 func(&fa.1)
1416 }
1417 }
1418
1419 #[document_type_parameters("The type of the first value in the pair.")]
1420 impl<First: Clone + 'static> RefTraversable for PairFirstAppliedBrand<First> {
1421 #[document_signature]
1423 #[document_type_parameters(
1424 "The lifetime.",
1425 "The brand.",
1426 "The input type.",
1427 "The output type.",
1428 "The applicative."
1429 )]
1430 #[document_parameters("The function.", "The pair.")]
1431 #[document_returns("The traversed result.")]
1432 #[document_examples]
1433 fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1448 func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1449 ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1450 ) -> 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>)>)
1451 where
1452 FnBrand: LiftFn + 'a,
1453 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1454 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1455 let first = ta.0.clone();
1456 F::map(move |b| Pair(first.clone(), b), func(&ta.1))
1457 }
1458 }
1459
1460 #[document_type_parameters("The type of the first value in the pair.")]
1461 impl<First: Clone + 'static> RefPointed for PairFirstAppliedBrand<First>
1462 where
1463 First: Monoid,
1464 {
1465 #[document_signature]
1467 #[document_type_parameters("The lifetime.", "The value type.")]
1468 #[document_parameters("The reference to wrap.")]
1469 #[document_returns("A pair containing `Monoid::empty()` and a clone of the value.")]
1470 #[document_examples]
1471 fn ref_pure<'a, A: Clone + 'a>(
1484 a: &A
1485 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1486 Pair(Monoid::empty(), a.clone())
1487 }
1488 }
1489
1490 #[document_type_parameters("The type of the first value in the pair.")]
1491 impl<First: Clone + 'static> RefLift for PairFirstAppliedBrand<First>
1492 where
1493 First: Semigroup,
1494 {
1495 #[document_signature]
1497 #[document_type_parameters("The lifetime.", "First input.", "Second input.", "Output.")]
1498 #[document_parameters("The binary function.", "The first pair.", "The second pair.")]
1499 #[document_returns("A pair with combined first values and the function result.")]
1500 #[document_examples]
1501 fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
1517 func: impl Fn(&A, &B) -> C + 'a,
1518 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1519 fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1520 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1521 Pair(Semigroup::append(fa.0.clone(), fb.0.clone()), func(&fa.1, &fb.1))
1522 }
1523 }
1524
1525 #[document_type_parameters("The type of the first value in the pair.")]
1526 impl<First: Clone + 'static> RefSemiapplicative for PairFirstAppliedBrand<First>
1527 where
1528 First: Semigroup,
1529 {
1530 #[document_signature]
1532 #[document_type_parameters(
1533 "The lifetime.",
1534 "The function brand.",
1535 "The input type.",
1536 "The output type."
1537 )]
1538 #[document_parameters(
1539 "The pair containing the function.",
1540 "The pair containing the value."
1541 )]
1542 #[document_returns("A pair with combined first values and the function result.")]
1543 #[document_examples]
1544 fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
1560 ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
1561 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1562 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1563 Pair(Semigroup::append(ff.0.clone(), fa.0.clone()), (*ff.1)(&fa.1))
1564 }
1565 }
1566
1567 #[document_type_parameters("The type of the first value in the pair.")]
1568 impl<First: Clone + 'static> RefSemimonad for PairFirstAppliedBrand<First>
1569 where
1570 First: Semigroup,
1571 {
1572 #[document_signature]
1574 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1575 #[document_parameters("The input pair.", "The function to apply by reference.")]
1576 #[document_returns("A pair with combined first values.")]
1577 #[document_examples]
1578 fn ref_bind<'a, A: 'a, B: 'a>(
1593 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1594 f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1595 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1596 let Pair(next_first, next_second) = f(&fa.1);
1597 Pair(Semigroup::append(fa.0.clone(), next_first), next_second)
1598 }
1599 }
1600
1601 impl_kind! {
1604 #[multi_brand]
1605 #[document_type_parameters("The type of the second value in the pair.")]
1606 impl<Second: 'static> for PairSecondAppliedBrand<Second> {
1607 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
1608 }
1609 }
1610
1611 #[document_type_parameters("The type of the second value in the pair.")]
1612 impl<Second: 'static> Functor for PairSecondAppliedBrand<Second> {
1613 #[document_signature]
1617 #[document_type_parameters(
1619 "The lifetime of the values.",
1620 "The type of the first value.",
1621 "The type of the result of applying the function."
1622 )]
1623 #[document_parameters("The function to apply to the first value.", "The pair to map over.")]
1625 #[document_returns(
1627 "A new pair containing the result of applying the function to the first value."
1628 )]
1629 #[document_examples]
1631 fn map<'a, A: 'a, B: 'a>(
1645 func: impl Fn(A) -> B + 'a,
1646 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1647 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1648 fa.map_first(func)
1649 }
1650 }
1651
1652 #[document_type_parameters("The type of the second value in the pair.")]
1653 impl<Second: Clone + 'static> Lift for PairSecondAppliedBrand<Second>
1654 where
1655 Second: Semigroup,
1656 {
1657 #[document_signature]
1661 #[document_type_parameters(
1663 "The lifetime of the values.",
1664 "The type of the first first value.",
1665 "The type of the second first value.",
1666 "The type of the result first value."
1667 )]
1668 #[document_parameters(
1670 "The binary function to apply to the first values.",
1671 "The first pair.",
1672 "The second pair."
1673 )]
1674 #[document_returns(
1676 "A new pair where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
1677 )]
1678 #[document_examples]
1679 fn lift2<'a, A, B, C>(
1697 func: impl Fn(A, B) -> C + 'a,
1698 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1699 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1700 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1701 where
1702 A: Clone + 'a,
1703 B: Clone + 'a,
1704 C: 'a, {
1705 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
1706 }
1707 }
1708
1709 #[document_type_parameters("The type of the second value in the pair.")]
1710 impl<Second: Clone + 'static> Pointed for PairSecondAppliedBrand<Second>
1711 where
1712 Second: Monoid,
1713 {
1714 #[document_signature]
1718 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1720 #[document_parameters("The value to wrap.")]
1722 #[document_returns("A pair containing `a` and the empty value of the second type.")]
1724 #[document_examples]
1726 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1737 Pair(a, Monoid::empty())
1738 }
1739 }
1740
1741 #[document_type_parameters("The type of the second value in the pair.")]
1742 impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairSecondAppliedBrand<Second> {}
1743
1744 #[document_type_parameters("The type of the second value in the pair.")]
1745 impl<Second: Clone + Semigroup + 'static> ApplySecond for PairSecondAppliedBrand<Second> {}
1746
1747 #[document_type_parameters("The type of the second value in the pair.")]
1748 impl<Second: Clone + 'static> Semiapplicative for PairSecondAppliedBrand<Second>
1749 where
1750 Second: Semigroup,
1751 {
1752 #[document_signature]
1756 #[document_type_parameters(
1758 "The lifetime of the values.",
1759 "The brand of the cloneable function wrapper.",
1760 "The type of the input value.",
1761 "The type of the output value."
1762 )]
1763 #[document_parameters(
1765 "The pair containing the function (in Err).",
1766 "The pair containing the value (in Err)."
1767 )]
1768 #[document_returns(
1770 "`Err(f(a))` if both are `Err`, otherwise the first success encountered."
1771 )]
1772 #[document_examples]
1773 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
1792 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1793 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1794 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1795 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1796 }
1797 }
1798
1799 #[document_type_parameters("The type of the second value in the pair.")]
1800 impl<Second: Clone + 'static> Semimonad for PairSecondAppliedBrand<Second>
1801 where
1802 Second: Semigroup,
1803 {
1804 #[document_signature]
1808 #[document_type_parameters(
1810 "The lifetime of the values.",
1811 "The type of the result of the first computation.",
1812 "The type of the result of the second computation."
1813 )]
1814 #[document_parameters("The first result.", "The function to apply to the error value.")]
1816 #[document_returns(
1818 "The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
1819 )]
1820 #[document_examples]
1822 fn bind<'a, A: 'a, B: 'a>(
1839 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1840 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1841 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1842 ma.bind_first(func)
1843 }
1844 }
1845
1846 #[document_type_parameters("The type of the second value in the pair.")]
1848 impl<Second: Clone + 'static> MonadRec for PairSecondAppliedBrand<Second>
1849 where
1850 Second: Monoid,
1851 {
1852 #[document_signature]
1860 #[document_type_parameters(
1862 "The lifetime of the computation.",
1863 "The type of the initial value and loop state.",
1864 "The type of the result."
1865 )]
1866 #[document_parameters("The step function.", "The initial value.")]
1868 #[document_returns("A pair with the final result and the accumulated second value.")]
1870 #[document_examples]
1872 fn tail_rec_m<'a, A: 'a, B: 'a>(
1896 func: impl Fn(
1897 A,
1898 )
1899 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1900 + 'a,
1901 initial: A,
1902 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1903 let mut acc: Second = Monoid::empty();
1904 let mut current = initial;
1905 loop {
1906 let Pair(step, second) = func(current);
1907 acc = Semigroup::append(acc, second);
1908 match step {
1909 ControlFlow::Continue(next) => current = next,
1910 ControlFlow::Break(b) => return Pair(b, acc),
1911 }
1912 }
1913 }
1914 }
1915
1916 #[document_type_parameters("The type of the second value in the pair.")]
1917 impl<Second: 'static> Foldable for PairSecondAppliedBrand<Second> {
1918 #[document_signature]
1922 #[document_type_parameters(
1924 "The lifetime of the values.",
1925 "The brand of the cloneable function to use.",
1926 "The type of the elements in the structure.",
1927 "The type of the accumulator."
1928 )]
1929 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1931 #[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
1933 #[document_examples]
1935 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1953 func: impl Fn(A, B) -> B + 'a,
1954 initial: B,
1955 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1956 ) -> B
1957 where
1958 FnBrand: CloneFn + 'a, {
1959 func(fa.0, initial)
1960 }
1961
1962 #[document_signature]
1966 #[document_type_parameters(
1968 "The lifetime of the values.",
1969 "The brand of the cloneable function to use.",
1970 "The type of the elements in the structure.",
1971 "The type of the accumulator."
1972 )]
1973 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1975 #[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
1977 #[document_examples]
1979 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1997 func: impl Fn(B, A) -> B + 'a,
1998 initial: B,
1999 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2000 ) -> B
2001 where
2002 FnBrand: CloneFn + 'a, {
2003 func(initial, fa.0)
2004 }
2005
2006 #[document_signature]
2010 #[document_type_parameters(
2012 "The lifetime of the values.",
2013 "The brand of the cloneable function to use.",
2014 "The type of the elements in the structure.",
2015 "The type of the monoid."
2016 )]
2017 #[document_parameters("The mapping function.", "The result to fold.")]
2019 #[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
2021 #[document_examples]
2023 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
2040 func: impl Fn(A) -> M + 'a,
2041 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2042 ) -> M
2043 where
2044 M: Monoid + 'a,
2045 FnBrand: CloneFn + 'a, {
2046 func(fa.0)
2047 }
2048 }
2049
2050 #[document_type_parameters("The type of the second value in the pair.")]
2051 impl<Second: Clone + 'static> Traversable for PairSecondAppliedBrand<Second> {
2052 #[document_signature]
2056 #[document_type_parameters(
2058 "The lifetime of the values.",
2059 "The type of the elements in the traversable structure.",
2060 "The type of the elements in the resulting traversable structure.",
2061 "The applicative context."
2062 )]
2063 #[document_parameters("The function to apply.", "The result to traverse.")]
2065 #[document_returns("The result wrapped in the applicative context.")]
2067 #[document_examples]
2069 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
2086 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2087 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2088 ) -> 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>)>)
2089 where
2090 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
2091 let Pair(first, second) = ta;
2092 F::map(move |b| Pair(b, second.clone()), func(first))
2093 }
2094
2095 #[document_signature]
2099 #[document_type_parameters(
2101 "The lifetime of the values.",
2102 "The type of the elements in the traversable structure.",
2103 "The applicative context."
2104 )]
2105 #[document_parameters("The result containing the applicative value.")]
2107 #[document_returns("The result wrapped in the applicative context.")]
2109 #[document_examples]
2111 fn sequence<'a, A: 'a + Clone, F: Applicative>(
2125 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>)>)
2126 ) -> 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>)>)
2127 where
2128 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
2129 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
2130 let Pair(first, second) = ta;
2131 F::map(move |a| Pair(a, second.clone()), first)
2132 }
2133 }
2134 #[document_type_parameters("The type of the second value in the pair.")]
2137 impl<Second: Clone + 'static> RefFunctor for PairSecondAppliedBrand<Second> {
2138 #[document_signature]
2140 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
2141 #[document_parameters("The function.", "The pair.")]
2142 #[document_returns("A new pair with the mapped first value.")]
2143 #[document_examples]
2144 fn ref_map<'a, A: 'a, B: 'a>(
2157 func: impl Fn(&A) -> B + 'a,
2158 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2159 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2160 Pair(func(&fa.0), fa.1.clone())
2161 }
2162 }
2163
2164 #[document_type_parameters("The type of the second value in the pair.")]
2165 impl<Second: Clone + 'static> RefFoldable for PairSecondAppliedBrand<Second> {
2166 #[document_signature]
2168 #[document_type_parameters(
2169 "The lifetime.",
2170 "The brand.",
2171 "The element type.",
2172 "The monoid type."
2173 )]
2174 #[document_parameters("The mapping function.", "The pair.")]
2175 #[document_returns("The monoid value.")]
2176 #[document_examples]
2177 fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
2191 func: impl Fn(&A) -> M + 'a,
2192 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2193 ) -> M
2194 where
2195 FnBrand: LiftFn + 'a,
2196 M: Monoid + 'a, {
2197 func(&fa.0)
2198 }
2199 }
2200
2201 #[document_type_parameters("The type of the second value in the pair.")]
2202 impl<Second: Clone + 'static> RefTraversable for PairSecondAppliedBrand<Second> {
2203 #[document_signature]
2205 #[document_type_parameters(
2206 "The lifetime.",
2207 "The brand.",
2208 "The input type.",
2209 "The output type.",
2210 "The applicative."
2211 )]
2212 #[document_parameters("The function.", "The pair.")]
2213 #[document_returns("The traversed result.")]
2214 #[document_examples]
2215 fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
2230 func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2231 ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2232 ) -> 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>)>)
2233 where
2234 FnBrand: LiftFn + 'a,
2235 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
2236 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
2237 let second = ta.1.clone();
2238 F::map(move |a| Pair(a, second.clone()), func(&ta.0))
2239 }
2240 }
2241
2242 #[document_type_parameters("The type of the second value in the pair.")]
2243 impl<Second: Clone + 'static> RefPointed for PairSecondAppliedBrand<Second>
2244 where
2245 Second: Monoid,
2246 {
2247 #[document_signature]
2249 #[document_type_parameters("The lifetime.", "The value type.")]
2250 #[document_parameters("The reference to wrap.")]
2251 #[document_returns("A pair containing a clone of the value and `Monoid::empty()`.")]
2252 #[document_examples]
2253 fn ref_pure<'a, A: Clone + 'a>(
2266 a: &A
2267 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
2268 Pair(a.clone(), Monoid::empty())
2269 }
2270 }
2271
2272 #[document_type_parameters("The type of the second value in the pair.")]
2273 impl<Second: Clone + 'static> RefLift for PairSecondAppliedBrand<Second>
2274 where
2275 Second: Semigroup,
2276 {
2277 #[document_signature]
2279 #[document_type_parameters("The lifetime.", "First input.", "Second input.", "Output.")]
2280 #[document_parameters("The binary function.", "The first pair.", "The second pair.")]
2281 #[document_returns("A pair with the function result and combined second values.")]
2282 #[document_examples]
2283 fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
2299 func: impl Fn(&A, &B) -> C + 'a,
2300 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2301 fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
2302 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
2303 Pair(func(&fa.0, &fb.0), Semigroup::append(fa.1.clone(), fb.1.clone()))
2304 }
2305 }
2306
2307 #[document_type_parameters("The type of the second value in the pair.")]
2308 impl<Second: Clone + 'static> RefSemiapplicative for PairSecondAppliedBrand<Second>
2309 where
2310 Second: Semigroup,
2311 {
2312 #[document_signature]
2314 #[document_type_parameters(
2315 "The lifetime.",
2316 "The function brand.",
2317 "The input type.",
2318 "The output type."
2319 )]
2320 #[document_parameters(
2321 "The pair containing the function.",
2322 "The pair containing the value."
2323 )]
2324 #[document_returns("A pair with the function result and combined second values.")]
2325 #[document_examples]
2326 fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
2342 ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
2343 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2344 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2345 Pair((*ff.0)(&fa.0), Semigroup::append(ff.1.clone(), fa.1.clone()))
2346 }
2347 }
2348
2349 #[document_type_parameters("The type of the second value in the pair.")]
2350 impl<Second: Clone + 'static> RefSemimonad for PairSecondAppliedBrand<Second>
2351 where
2352 Second: Semigroup,
2353 {
2354 #[document_signature]
2356 #[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
2357 #[document_parameters("The input pair.", "The function to apply by reference.")]
2358 #[document_returns("A pair with combined second values.")]
2359 #[document_examples]
2360 fn ref_bind<'a, A: 'a, B: 'a>(
2375 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2376 f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2377 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2378 let Pair(next_first, next_second) = f(&fa.0);
2379 Pair(next_first, Semigroup::append(fa.1.clone(), next_second))
2380 }
2381 }
2382}
2383pub use inner::*;
2384
2385#[cfg(test)]
2386mod tests {
2387 use {
2388 super::inner::*,
2389 crate::{
2390 brands::*,
2391 classes::{
2392 semiapplicative::apply as explicit_apply,
2393 *,
2394 },
2395 functions::*,
2396 },
2397 quickcheck_macros::quickcheck,
2398 };
2399
2400 #[test]
2404 fn test_bimap() {
2405 let x = Pair(1, 5);
2406 assert_eq!(
2407 explicit::bimap::<PairBrand, _, _, _, _, _, _>((|a| a + 1, |b| b * 2), x),
2408 Pair(2, 10)
2409 );
2410 }
2411
2412 #[quickcheck]
2416 fn bifunctor_identity(
2417 first: String,
2418 second: i32,
2419 ) -> bool {
2420 let x = Pair(first, second);
2421 explicit::bimap::<PairBrand, _, _, _, _, _, _>((identity, identity), x.clone()) == x
2422 }
2423
2424 #[quickcheck]
2426 fn bifunctor_composition(
2427 first: i32,
2428 second: i32,
2429 ) -> bool {
2430 let x = Pair(first, second);
2431 let f = |x: i32| x.wrapping_add(1);
2432 let g = |x: i32| x.wrapping_mul(2);
2433 let h = |x: i32| x.wrapping_sub(1);
2434 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
2435
2436 explicit::bimap::<PairBrand, _, _, _, _, _, _>((compose(f, g), compose(h, i)), x)
2437 == explicit::bimap::<PairBrand, _, _, _, _, _, _>(
2438 (f, h),
2439 explicit::bimap::<PairBrand, _, _, _, _, _, _>((g, i), x),
2440 )
2441 }
2442
2443 #[quickcheck]
2447 fn functor_identity(
2448 first: String,
2449 second: i32,
2450 ) -> bool {
2451 let x = Pair(first, second);
2452 explicit::map::<PairFirstAppliedBrand<String>, _, _, _, _>(identity, x.clone()) == x
2453 }
2454
2455 #[quickcheck]
2457 fn functor_composition(
2458 first: String,
2459 second: i32,
2460 ) -> bool {
2461 let x = Pair(first, second);
2462 let f = |x: i32| x.wrapping_add(1);
2463 let g = |x: i32| x.wrapping_mul(2);
2464 explicit::map::<PairFirstAppliedBrand<String>, _, _, _, _>(compose(f, g), x.clone())
2465 == explicit::map::<PairFirstAppliedBrand<String>, _, _, _, _>(
2466 f,
2467 explicit::map::<PairFirstAppliedBrand<String>, _, _, _, _>(g, x),
2468 )
2469 }
2470
2471 #[quickcheck]
2475 fn applicative_identity(
2476 first: String,
2477 second: i32,
2478 ) -> bool {
2479 let v = Pair(first, second);
2480 explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
2481 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as LiftFn>::new(identity)),
2482 v.clone(),
2483 ) == v
2484 }
2485
2486 #[quickcheck]
2488 fn applicative_homomorphism(x: i32) -> bool {
2489 let f = |x: i32| x.wrapping_mul(2);
2490 explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
2491 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as LiftFn>::new(f)),
2492 pure::<PairFirstAppliedBrand<String>, _>(x),
2493 ) == pure::<PairFirstAppliedBrand<String>, _>(f(x))
2494 }
2495
2496 #[quickcheck]
2498 fn applicative_composition(
2499 w_first: String,
2500 w_second: i32,
2501 u_seed: i32,
2502 v_seed: i32,
2503 ) -> bool {
2504 let w = Pair(w_first, w_second);
2505
2506 let u_fn = <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_add(u_seed));
2507 let u = pure::<PairFirstAppliedBrand<String>, _>(u_fn);
2508
2509 let v_fn = <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_mul(v_seed));
2510 let v = pure::<PairFirstAppliedBrand<String>, _>(v_fn);
2511
2512 let vw =
2514 explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
2515 let rhs = explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u.clone(), vw);
2516
2517 let compose_fn = <RcFnBrand as LiftFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
2519 let f = f.clone();
2520 <RcFnBrand as LiftFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
2521 let f = f.clone();
2522 let g = g.clone();
2523 <RcFnBrand as LiftFn>::new(move |x| f(g(x)))
2524 })
2525 });
2526
2527 let pure_compose = pure::<PairFirstAppliedBrand<String>, _>(compose_fn);
2528 let u_applied =
2529 explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(pure_compose, u);
2530 let uv = explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u_applied, v);
2531 let lhs = explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(uv, w);
2532
2533 lhs == rhs
2534 }
2535
2536 #[quickcheck]
2538 fn applicative_interchange(
2539 y: i32,
2540 u_seed: i32,
2541 ) -> bool {
2542 let f = move |x: i32| x.wrapping_mul(u_seed);
2544 let u = pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as LiftFn>::new(f));
2545
2546 let lhs = explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
2547 u.clone(),
2548 pure::<PairFirstAppliedBrand<String>, _>(y),
2549 );
2550
2551 let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
2552 let rhs = explicit_apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
2553 pure::<PairFirstAppliedBrand<String>, _>(rhs_fn),
2554 u,
2555 );
2556
2557 lhs == rhs
2558 }
2559
2560 #[quickcheck]
2564 fn monad_left_identity(a: i32) -> bool {
2565 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
2566 explicit::bind::<PairFirstAppliedBrand<String>, _, _, _, _>(
2567 pure::<PairFirstAppliedBrand<String>, _>(a),
2568 f,
2569 ) == f(a)
2570 }
2571
2572 #[quickcheck]
2574 fn monad_right_identity(
2575 first: String,
2576 second: i32,
2577 ) -> bool {
2578 let m = Pair(first, second);
2579 explicit::bind::<PairFirstAppliedBrand<String>, _, _, _, _>(
2580 m.clone(),
2581 pure::<PairFirstAppliedBrand<String>, _>,
2582 ) == m
2583 }
2584
2585 #[quickcheck]
2587 fn monad_associativity(
2588 first: String,
2589 second: i32,
2590 ) -> bool {
2591 let m = Pair(first, second);
2592 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
2593 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
2594 explicit::bind::<PairFirstAppliedBrand<String>, _, _, _, _>(
2595 explicit::bind::<PairFirstAppliedBrand<String>, _, _, _, _>(m.clone(), f),
2596 g,
2597 ) == explicit::bind::<PairFirstAppliedBrand<String>, _, _, _, _>(m, |x| {
2598 explicit::bind::<PairFirstAppliedBrand<String>, _, _, _, _>(f(x), g)
2599 })
2600 }
2601
2602 #[quickcheck]
2606 fn monad_rec_first_applied_identity(x: i32) -> bool {
2607 use {
2608 crate::classes::monad_rec::tail_rec_m,
2609 core::ops::ControlFlow,
2610 };
2611 tail_rec_m::<PairFirstAppliedBrand<String>, _, _>(
2612 |a| Pair(String::new(), ControlFlow::Break(a)),
2613 x,
2614 ) == Pair(String::new(), x)
2615 }
2616
2617 #[test]
2619 fn monad_rec_first_applied_accumulation() {
2620 use {
2621 crate::classes::monad_rec::tail_rec_m,
2622 core::ops::ControlFlow,
2623 };
2624 let result = tail_rec_m::<PairFirstAppliedBrand<String>, _, _>(
2625 |n: i32| {
2626 if n < 3 {
2627 Pair(format!("{n},"), ControlFlow::Continue(n + 1))
2628 } else {
2629 Pair(format!("{n}"), ControlFlow::Break(n))
2630 }
2631 },
2632 0,
2633 );
2634 assert_eq!(result, Pair("0,1,2,3".to_string(), 3));
2635 }
2636
2637 #[test]
2639 fn monad_rec_first_applied_stack_safety() {
2640 use {
2641 crate::classes::monad_rec::tail_rec_m,
2642 core::ops::ControlFlow,
2643 };
2644 let iterations: i64 = 200_000;
2645 let result = tail_rec_m::<PairFirstAppliedBrand<Vec<()>>, _, _>(
2646 |acc| {
2647 if acc < iterations {
2648 Pair(vec![], ControlFlow::Continue(acc + 1))
2649 } else {
2650 Pair(vec![], ControlFlow::Break(acc))
2651 }
2652 },
2653 0i64,
2654 );
2655 assert_eq!(result, Pair(vec![], iterations));
2656 }
2657
2658 #[quickcheck]
2662 fn monad_rec_second_applied_identity(x: i32) -> bool {
2663 use {
2664 crate::classes::monad_rec::tail_rec_m,
2665 core::ops::ControlFlow,
2666 };
2667 tail_rec_m::<PairSecondAppliedBrand<String>, _, _>(
2668 |a| Pair(ControlFlow::Break(a), String::new()),
2669 x,
2670 ) == Pair(x, String::new())
2671 }
2672
2673 #[test]
2675 fn monad_rec_second_applied_accumulation() {
2676 use {
2677 crate::classes::monad_rec::tail_rec_m,
2678 core::ops::ControlFlow,
2679 };
2680 let result = tail_rec_m::<PairSecondAppliedBrand<String>, _, _>(
2681 |n: i32| {
2682 if n < 3 {
2683 Pair(ControlFlow::Continue(n + 1), format!("{n},"))
2684 } else {
2685 Pair(ControlFlow::Break(n), format!("{n}"))
2686 }
2687 },
2688 0,
2689 );
2690 assert_eq!(result, Pair(3, "0,1,2,3".to_string()));
2691 }
2692
2693 #[test]
2695 fn monad_rec_second_applied_stack_safety() {
2696 use {
2697 crate::classes::monad_rec::tail_rec_m,
2698 core::ops::ControlFlow,
2699 };
2700 let iterations: i64 = 200_000;
2701 let result = tail_rec_m::<PairSecondAppliedBrand<Vec<()>>, _, _>(
2702 |acc| {
2703 if acc < iterations {
2704 Pair(ControlFlow::Continue(acc + 1), vec![])
2705 } else {
2706 Pair(ControlFlow::Break(acc), vec![])
2707 }
2708 },
2709 0i64,
2710 );
2711 assert_eq!(result, Pair(iterations, vec![]));
2712 }
2713
2714 #[quickcheck]
2718 fn ref_bifunctor_identity(
2719 a: i32,
2720 b: i32,
2721 ) -> bool {
2722 let p = Pair(a, b);
2723 explicit::bimap::<PairBrand, _, _, _, _, _, _>((|x: &i32| *x, |x: &i32| *x), &p) == p
2724 }
2725
2726 #[quickcheck]
2728 fn ref_bifunctor_composition(
2729 a: i32,
2730 b: i32,
2731 ) -> bool {
2732 let p = Pair(a, b);
2733 let f1 = |x: &i32| x.wrapping_add(1);
2734 let f2 = |x: &i32| x.wrapping_mul(2);
2735 let g1 = |x: &i32| x.wrapping_add(10);
2736 let g2 = |x: &i32| x.wrapping_mul(3);
2737 explicit::bimap::<PairBrand, _, _, _, _, _, _>(
2738 (|x: &i32| f2(&f1(x)), |x: &i32| g2(&g1(x))),
2739 &p,
2740 ) == explicit::bimap::<PairBrand, _, _, _, _, _, _>(
2741 (f2, g2),
2742 &explicit::bimap::<PairBrand, _, _, _, _, _, _>((f1, g1), &p),
2743 )
2744 }
2745
2746 #[quickcheck]
2750 fn ref_bifoldable_fold_map(
2751 a: i32,
2752 b: i32,
2753 ) -> bool {
2754 let p = Pair(a, b);
2755 let result = explicit::bi_fold_map::<RcFnBrand, PairBrand, _, _, _, _, _>(
2756 (|x: &i32| x.to_string(), |x: &i32| x.to_string()),
2757 &p,
2758 );
2759 result == format!("{}{}", a, b)
2760 }
2761
2762 #[quickcheck]
2766 fn ref_bitraversable_consistency(
2767 a: i32,
2768 b: i32,
2769 ) -> bool {
2770 let p = Pair(a, b);
2771 let f = |x: &i32| Some(x.wrapping_add(1));
2772 let g = |x: &i32| Some(x.wrapping_mul(2));
2773 let traversed = explicit::bi_traverse::<RcFnBrand, PairBrand, _, _, _, _, OptionBrand, _, _>(
2774 (f, g),
2775 &p,
2776 );
2777 let mapped_then_sequenced =
2778 ref_bi_sequence::<PairBrand, RcFnBrand, _, _, OptionBrand>(&explicit::bimap::<
2779 PairBrand,
2780 _,
2781 _,
2782 _,
2783 _,
2784 _,
2785 _,
2786 >((f, g), &p));
2787 traversed == mapped_then_sequenced
2788 }
2789}