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 Pointed,
28 Semiapplicative,
29 Semigroup,
30 Semimonad,
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 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
57 pub struct Pair<First, Second>(
58 pub First,
60 pub Second,
62 );
63
64 impl_kind! {
65 for PairBrand {
66 type Of<First,Second> = Pair<First, Second>;
67 }
68 }
69
70 impl_kind! {
71 for PairBrand {
72 type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
73 }
74 }
75
76 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
77 #[document_parameters("The pair instance.")]
78 impl<First, Second> Pair<First, Second> {
79 #[document_signature]
83 #[document_type_parameters(
85 "The type of the mapped first value.",
86 "The type of the mapped second value."
87 )]
88 #[document_parameters(
90 "The function to apply to the first value.",
91 "The function to apply to the second value."
92 )]
93 #[document_returns("A new pair containing the mapped values.")]
95 #[document_examples]
97 pub fn bimap<B, D>(
105 self,
106 f: impl FnOnce(First) -> B,
107 g: impl FnOnce(Second) -> D,
108 ) -> Pair<B, D> {
109 Pair(f(self.0), g(self.1))
110 }
111
112 #[document_signature]
116 #[document_type_parameters("The type of the mapped first value.")]
118 #[document_parameters("The function to apply to the first value.")]
120 #[document_returns("A new pair with the transformed first value.")]
122 #[document_examples]
124 pub fn map_first<B>(
132 self,
133 f: impl FnOnce(First) -> B,
134 ) -> Pair<B, Second> {
135 Pair(f(self.0), self.1)
136 }
137
138 #[document_signature]
142 #[document_type_parameters("The type of the mapped second value.")]
144 #[document_parameters("The function to apply to the second value.")]
146 #[document_returns("A new pair with the transformed second value.")]
148 #[document_examples]
150 pub fn map_second<D>(
158 self,
159 g: impl FnOnce(Second) -> D,
160 ) -> Pair<First, D> {
161 Pair(self.0, g(self.1))
162 }
163
164 #[document_signature]
169 #[document_type_parameters("The result type.")]
171 #[document_parameters(
173 "The function to apply to the first value.",
174 "The function to apply to the second value.",
175 "The function to combine the results."
176 )]
177 #[document_returns("The combined result.")]
179 #[document_examples]
181 pub fn fold<C>(
190 self,
191 f: impl FnOnce(First) -> C,
192 g: impl FnOnce(Second) -> C,
193 combine: impl FnOnce(C, C) -> C,
194 ) -> C {
195 combine(f(self.0), g(self.1))
196 }
197
198 #[document_signature]
202 #[document_type_parameters("The accumulator type.")]
204 #[document_parameters(
206 "The step function for the first value.",
207 "The step function for the second value.",
208 "The initial accumulator."
209 )]
210 #[document_returns("The result of folding: `f(first, g(second, z))`.")]
212 #[document_examples]
214 pub fn bi_fold_right<C>(
222 self,
223 f: impl FnOnce(First, C) -> C,
224 g: impl FnOnce(Second, C) -> C,
225 z: C,
226 ) -> C {
227 f(self.0, g(self.1, z))
228 }
229
230 #[document_signature]
234 #[document_type_parameters("The accumulator type.")]
236 #[document_parameters(
238 "The step function for the first value.",
239 "The step function for the second value.",
240 "The initial accumulator."
241 )]
242 #[document_returns("The result of folding: `g(f(z, first), second)`.")]
244 #[document_examples]
246 pub fn bi_fold_left<C>(
254 self,
255 f: impl FnOnce(C, First) -> C,
256 g: impl FnOnce(C, Second) -> C,
257 z: C,
258 ) -> C {
259 g(f(z, self.0), self.1)
260 }
261
262 #[document_signature]
266 #[document_type_parameters("The monoid type.")]
268 #[document_parameters(
270 "The function mapping the first value to the monoid.",
271 "The function mapping the second value to the monoid."
272 )]
273 #[document_returns("The combined monoid value.")]
275 #[document_examples]
277 pub fn bi_fold_map<M: Semigroup>(
285 self,
286 f: impl FnOnce(First) -> M,
287 g: impl FnOnce(Second) -> M,
288 ) -> M {
289 Semigroup::append(f(self.0), g(self.1))
290 }
291 }
292
293 #[document_type_parameters(
294 "The lifetime of the values.",
295 "The type of the first value.",
296 "The type of the second value."
297 )]
298 #[document_parameters("The pair instance.")]
299 impl<'a, First: 'a, Second: 'a> Pair<First, Second> {
300 #[document_signature]
304 #[document_type_parameters(
306 "The output type for the first value.",
307 "The output type for the second value.",
308 "The applicative context."
309 )]
310 #[document_parameters(
312 "The function for the first value.",
313 "The function for the second value."
314 )]
315 #[document_returns("A pair of the transformed values wrapped in the applicative context.")]
317 #[document_examples]
319 pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
331 self,
332 f: impl Fn(First) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
333 g: impl Fn(Second) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
334 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Pair<C, D>>)
335 where
336 Pair<C, D>: Clone, {
337 F::lift2(|c, d| Pair(c, d), f(self.0), g(self.1))
338 }
339 }
340
341 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
342 #[document_parameters("The pair instance.")]
343 impl<First: Semigroup, Second> Pair<First, Second> {
344 #[document_signature]
349 #[document_type_parameters("The type of the new second value.")]
351 #[document_parameters("The function to apply to the second value.")]
353 #[document_returns(
355 "A new pair where the first values are combined and the second value is transformed."
356 )]
357 #[document_examples]
359 pub fn bind<C>(
369 self,
370 f: impl FnOnce(Second) -> Pair<First, C>,
371 ) -> Pair<First, C> {
372 let Pair(first, second) = self;
373 let Pair(next_first, next_second) = f(second);
374 Pair(Semigroup::append(first, next_first), next_second)
375 }
376 }
377
378 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
379 #[document_parameters("The pair instance.")]
380 impl<First, Second: Semigroup> Pair<First, Second> {
381 #[document_signature]
386 #[document_type_parameters("The type of the new first value.")]
388 #[document_parameters("The function to apply to the first value.")]
390 #[document_returns(
392 "A new pair where the first value is transformed and the second values are combined."
393 )]
394 #[document_examples]
396 pub fn bind_first<C>(
406 self,
407 f: impl FnOnce(First) -> Pair<C, Second>,
408 ) -> Pair<C, Second> {
409 let Pair(first, second) = self;
410 let Pair(next_first, next_second) = f(first);
411 Pair(next_first, Semigroup::append(second, next_second))
412 }
413 }
414
415 impl Bifunctor for PairBrand {
416 #[document_signature]
420 #[document_type_parameters(
422 "The lifetime of the values.",
423 "The type of the first value.",
424 "The type of the mapped first value.",
425 "The type of the second value.",
426 "The type of the mapped second value."
427 )]
428 #[document_parameters(
430 "The function to apply to the first value.",
431 "The function to apply to the second value.",
432 "The pair to map over."
433 )]
434 #[document_returns("A new pair containing the mapped values.")]
436 #[document_examples]
437 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
450 f: impl Fn(A) -> B + 'a,
451 g: impl Fn(C) -> D + 'a,
452 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
453 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
454 p.bimap(f, g)
455 }
456 }
457
458 impl Bifoldable for PairBrand {
459 #[document_signature]
463 #[document_type_parameters(
465 "The lifetime of the values.",
466 "The brand of the cloneable function to use.",
467 "The type of the first value.",
468 "The type of the second value.",
469 "The accumulator type."
470 )]
471 #[document_parameters(
473 "The step function for the first value.",
474 "The step function for the second value.",
475 "The initial accumulator.",
476 "The pair to fold."
477 )]
478 #[document_returns("`f(a, g(b, z))`.")]
480 #[document_examples]
481 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
496 f: impl Fn(A, C) -> C + 'a,
497 g: impl Fn(B, C) -> C + 'a,
498 z: C,
499 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
500 ) -> C {
501 p.bi_fold_right(f, g, z)
502 }
503
504 #[document_signature]
508 #[document_type_parameters(
510 "The lifetime of the values.",
511 "The brand of the cloneable function to use.",
512 "The type of the first value.",
513 "The type of the second value.",
514 "The accumulator type."
515 )]
516 #[document_parameters(
518 "The step function for the first value.",
519 "The step function for the second value.",
520 "The initial accumulator.",
521 "The pair to fold."
522 )]
523 #[document_returns("`g(f(z, a), b)`.")]
525 #[document_examples]
526 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
541 f: impl Fn(C, A) -> C + 'a,
542 g: impl Fn(C, B) -> C + 'a,
543 z: C,
544 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
545 ) -> C {
546 p.bi_fold_left(f, g, z)
547 }
548
549 #[document_signature]
553 #[document_type_parameters(
555 "The lifetime of the values.",
556 "The brand of the cloneable function to use.",
557 "The type of the first value.",
558 "The type of the second value.",
559 "The monoid type."
560 )]
561 #[document_parameters(
563 "The function mapping the first value to the monoid.",
564 "The function mapping the second value to the monoid.",
565 "The pair to fold."
566 )]
567 #[document_returns("`Semigroup::append(f(a), g(b))`.")]
569 #[document_examples]
570 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
588 f: impl Fn(A) -> M + 'a,
589 g: impl Fn(B) -> M + 'a,
590 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
591 ) -> M
592 where
593 M: Monoid + 'a, {
594 p.bi_fold_map(f, g)
595 }
596 }
597
598 impl Bitraversable for PairBrand {
599 #[document_signature]
604 #[document_type_parameters(
606 "The lifetime of the values.",
607 "The type of the first value.",
608 "The type of the second value.",
609 "The output type for the first value.",
610 "The output type for the second value.",
611 "The applicative context."
612 )]
613 #[document_parameters(
615 "The function applied to the first value.",
616 "The function applied to the second value.",
617 "The pair to traverse."
618 )]
619 #[document_returns("`lift2(Pair, f(a), g(b))`.")]
621 #[document_examples]
622 fn bi_traverse<
641 'a,
642 A: 'a + Clone,
643 B: 'a + Clone,
644 C: 'a + Clone,
645 D: 'a + Clone,
646 F: Applicative,
647 >(
648 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
649 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
650 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
651 ) -> 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>)>)
652 {
653 p.bi_traverse::<C, D, F>(f, g)
654 }
655 }
656
657 impl_kind! {
660 #[document_type_parameters("The type of the first value in the pair.")]
661 impl<First: 'static> for PairFirstAppliedBrand<First> {
662 type Of<'a, A: 'a>: 'a = Pair<First, A>;
663 }
664 }
665
666 #[document_type_parameters("The type of the first value in the pair.")]
667 impl<First: 'static> Functor for PairFirstAppliedBrand<First> {
668 #[document_signature]
672 #[document_type_parameters(
674 "The lifetime of the values.",
675 "The type of the second value.",
676 "The type of the result of applying the function."
677 )]
678 #[document_parameters(
680 "The function to apply to the second value.",
681 "The pair to map over."
682 )]
683 #[document_returns(
685 "A new pair containing the result of applying the function to the second value."
686 )]
687 #[document_examples]
688 fn map<'a, A: 'a, B: 'a>(
699 func: impl Fn(A) -> B + 'a,
700 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
701 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
702 fa.map_second(func)
703 }
704 }
705
706 #[document_type_parameters("The type of the first value in the pair.")]
707 impl<First: Clone + 'static> Lift for PairFirstAppliedBrand<First>
708 where
709 First: Semigroup,
710 {
711 #[document_signature]
715 #[document_type_parameters(
717 "The lifetime of the values.",
718 "The type of the first second value.",
719 "The type of the second second value.",
720 "The type of the result second value."
721 )]
722 #[document_parameters(
724 "The binary function to apply to the second values.",
725 "The first pair.",
726 "The second pair."
727 )]
728 #[document_returns(
730 "A new pair where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
731 )]
732 #[document_examples]
733 fn lift2<'a, A, B, C>(
751 func: impl Fn(A, B) -> C + 'a,
752 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
753 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
754 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
755 where
756 A: Clone + 'a,
757 B: Clone + 'a,
758 C: 'a, {
759 let Pair(fa_first, fa_second) = fa;
760 let Pair(fb_first, fb_second) = fb;
761 Pair(Semigroup::append(fa_first, fb_first), func(fa_second, fb_second))
762 }
763 }
764
765 #[document_type_parameters("The type of the first value in the pair.")]
766 impl<First: Clone + 'static> Pointed for PairFirstAppliedBrand<First>
767 where
768 First: Monoid,
769 {
770 #[document_signature]
774 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
776 #[document_parameters("The value to wrap.")]
778 #[document_returns("A pair containing the empty value of the first type and `a`.")]
780 #[document_examples]
782 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
793 Pair(Monoid::empty(), a)
794 }
795 }
796
797 #[document_type_parameters("The type of the first value in the pair.")]
798 impl<First: Clone + Semigroup + 'static> ApplyFirst for PairFirstAppliedBrand<First> {}
799
800 #[document_type_parameters("The type of the first value in the pair.")]
801 impl<First: Clone + Semigroup + 'static> ApplySecond for PairFirstAppliedBrand<First> {}
802
803 #[document_type_parameters("The type of the first value in the pair.")]
804 impl<First: Clone + 'static> Semiapplicative for PairFirstAppliedBrand<First>
805 where
806 First: Semigroup,
807 {
808 #[document_signature]
812 #[document_type_parameters(
814 "The lifetime of the values.",
815 "The brand of the cloneable function wrapper.",
816 "The type of the input value.",
817 "The type of the output value."
818 )]
819 #[document_parameters(
821 "The pair containing the function.",
822 "The pair containing the value."
823 )]
824 #[document_returns(
826 "A new pair where the first values are combined and the function is applied to the second value."
827 )]
828 #[document_examples]
829 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
844 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
845 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
846 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
847 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
848 }
849 }
850
851 #[document_type_parameters("The type of the first value in the pair.")]
852 impl<First: Clone + 'static> Semimonad for PairFirstAppliedBrand<First>
853 where
854 First: Semigroup,
855 {
856 #[document_signature]
860 #[document_type_parameters(
862 "The lifetime of the values.",
863 "The type of the result of the first computation.",
864 "The type of the result of the second computation."
865 )]
866 #[document_parameters("The first pair.", "The function to apply to the second value.")]
868 #[document_returns("A new pair where the first values are combined.")]
870 #[document_examples]
872 fn bind<'a, A: 'a, B: 'a>(
889 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
890 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
891 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
892 ma.bind(func)
893 }
894 }
895
896 #[document_type_parameters("The type of the first value in the pair.")]
897 impl<First: 'static> Foldable for PairFirstAppliedBrand<First> {
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 pair to fold.")]
911 #[document_returns("`func(a, 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.1, 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(
951 "The function to apply to the accumulator and each element.",
952 "The initial value of the accumulator.",
953 "The identity to fold."
954 )]
955 #[document_returns("`func(initial, a)`.")]
957 #[document_examples]
958 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
972 func: impl Fn(B, A) -> B + 'a,
973 initial: B,
974 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
975 ) -> B
976 where
977 FnBrand: CloneableFn + 'a, {
978 func(initial, fa.1)
979 }
980
981 #[document_signature]
985 #[document_type_parameters(
987 "The lifetime of the values.",
988 "The brand of the cloneable function to use.",
989 "The type of the elements in the structure.",
990 "The type of the monoid."
991 )]
992 #[document_parameters("The mapping function.", "The pair to fold.")]
994 #[document_returns("`func(a)`.")]
996 #[document_examples]
998 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.1)
1019 }
1020 }
1021
1022 #[document_type_parameters("The type of the first value in the pair.")]
1023 impl<First: Clone + 'static> Traversable for PairFirstAppliedBrand<First> {
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(
1037 "The function to apply to each element, returning a value in an applicative context.",
1038 "The pair to traverse."
1039 )]
1040 #[document_returns("The pair wrapped in the applicative context.")]
1042 #[document_examples]
1043 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1057 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1058 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1059 ) -> 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>)>)
1060 where
1061 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1062 let Pair(first, second) = ta;
1063 F::map(move |b| Pair(first.clone(), b), func(second))
1064 }
1065
1066 #[document_signature]
1070 #[document_type_parameters(
1072 "The lifetime of the values.",
1073 "The type of the elements in the traversable structure.",
1074 "The applicative context."
1075 )]
1076 #[document_parameters("The pair containing the applicative value.")]
1078 #[document_returns("The pair wrapped in the applicative context.")]
1080 #[document_examples]
1082 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1096 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>)>)
1097 ) -> 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>)>)
1098 where
1099 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1100 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1101 let Pair(first, second) = ta;
1102 F::map(move |a| Pair(first.clone(), a), second)
1103 }
1104 }
1105
1106 impl_kind! {
1109 #[document_type_parameters("The type of the second value in the pair.")]
1110 impl<Second: 'static> for PairSecondAppliedBrand<Second> {
1111 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
1112 }
1113 }
1114
1115 #[document_type_parameters("The type of the second value in the pair.")]
1116 impl<Second: 'static> Functor for PairSecondAppliedBrand<Second> {
1117 #[document_signature]
1121 #[document_type_parameters(
1123 "The lifetime of the values.",
1124 "The type of the first value.",
1125 "The type of the result of applying the function."
1126 )]
1127 #[document_parameters("The function to apply to the first value.", "The pair to map over.")]
1129 #[document_returns(
1131 "A new pair containing the result of applying the function to the first value."
1132 )]
1133 #[document_examples]
1135 fn map<'a, A: 'a, B: 'a>(
1146 func: impl Fn(A) -> B + 'a,
1147 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1148 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1149 fa.map_first(func)
1150 }
1151 }
1152
1153 #[document_type_parameters("The type of the second value in the pair.")]
1154 impl<Second: Clone + 'static> Lift for PairSecondAppliedBrand<Second>
1155 where
1156 Second: Semigroup,
1157 {
1158 #[document_signature]
1162 #[document_type_parameters(
1164 "The lifetime of the values.",
1165 "The type of the first first value.",
1166 "The type of the second first value.",
1167 "The type of the result first value."
1168 )]
1169 #[document_parameters(
1171 "The binary function to apply to the first values.",
1172 "The first pair.",
1173 "The second pair."
1174 )]
1175 #[document_returns(
1177 "A new pair where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
1178 )]
1179 #[document_examples]
1180 fn lift2<'a, A, B, C>(
1198 func: impl Fn(A, B) -> C + 'a,
1199 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1200 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1201 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1202 where
1203 A: Clone + 'a,
1204 B: Clone + 'a,
1205 C: 'a, {
1206 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
1207 }
1208 }
1209
1210 #[document_type_parameters("The type of the second value in the pair.")]
1211 impl<Second: Clone + 'static> Pointed for PairSecondAppliedBrand<Second>
1212 where
1213 Second: Monoid,
1214 {
1215 #[document_signature]
1219 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1221 #[document_parameters("The value to wrap.")]
1223 #[document_returns("A pair containing `a` and the empty value of the second type.")]
1225 #[document_examples]
1227 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1238 Pair(a, Monoid::empty())
1239 }
1240 }
1241
1242 #[document_type_parameters("The type of the second value in the pair.")]
1243 impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairSecondAppliedBrand<Second> {}
1244
1245 #[document_type_parameters("The type of the second value in the pair.")]
1246 impl<Second: Clone + Semigroup + 'static> ApplySecond for PairSecondAppliedBrand<Second> {}
1247
1248 #[document_type_parameters("The type of the second value in the pair.")]
1249 impl<Second: Clone + 'static> Semiapplicative for PairSecondAppliedBrand<Second>
1250 where
1251 Second: Semigroup,
1252 {
1253 #[document_signature]
1257 #[document_type_parameters(
1259 "The lifetime of the values.",
1260 "The brand of the cloneable function wrapper.",
1261 "The type of the input value.",
1262 "The type of the output value."
1263 )]
1264 #[document_parameters(
1266 "The pair containing the function (in Err).",
1267 "The pair containing the value (in Err)."
1268 )]
1269 #[document_returns(
1271 "`Err(f(a))` if both are `Err`, otherwise the first success encountered."
1272 )]
1273 #[document_examples]
1274 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1289 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1290 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1291 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1292 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1293 }
1294 }
1295
1296 #[document_type_parameters("The type of the second value in the pair.")]
1297 impl<Second: Clone + 'static> Semimonad for PairSecondAppliedBrand<Second>
1298 where
1299 Second: Semigroup,
1300 {
1301 #[document_signature]
1305 #[document_type_parameters(
1307 "The lifetime of the values.",
1308 "The type of the result of the first computation.",
1309 "The type of the result of the second computation."
1310 )]
1311 #[document_parameters("The first result.", "The function to apply to the error value.")]
1313 #[document_returns(
1315 "The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
1316 )]
1317 #[document_examples]
1319 fn bind<'a, A: 'a, B: 'a>(
1336 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1337 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1338 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1339 ma.bind_first(func)
1340 }
1341 }
1342
1343 #[document_type_parameters("The type of the second value in the pair.")]
1344 impl<Second: 'static> Foldable for PairSecondAppliedBrand<Second> {
1345 #[document_signature]
1349 #[document_type_parameters(
1351 "The lifetime of the values.",
1352 "The brand of the cloneable function to use.",
1353 "The type of the elements in the structure.",
1354 "The type of the accumulator."
1355 )]
1356 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1358 #[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
1360 #[document_examples]
1362 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1376 func: impl Fn(A, B) -> B + 'a,
1377 initial: B,
1378 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1379 ) -> B
1380 where
1381 FnBrand: CloneableFn + 'a, {
1382 func(fa.0, initial)
1383 }
1384
1385 #[document_signature]
1389 #[document_type_parameters(
1391 "The lifetime of the values.",
1392 "The brand of the cloneable function to use.",
1393 "The type of the elements in the structure.",
1394 "The type of the accumulator."
1395 )]
1396 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1398 #[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
1400 #[document_examples]
1402 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1416 func: impl Fn(B, A) -> B + 'a,
1417 initial: B,
1418 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1419 ) -> B
1420 where
1421 FnBrand: CloneableFn + 'a, {
1422 func(initial, fa.0)
1423 }
1424
1425 #[document_signature]
1429 #[document_type_parameters(
1431 "The lifetime of the values.",
1432 "The brand of the cloneable function to use.",
1433 "The type of the elements in the structure.",
1434 "The type of the monoid."
1435 )]
1436 #[document_parameters("The mapping function.", "The result to fold.")]
1438 #[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
1440 #[document_examples]
1442 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1459 func: impl Fn(A) -> M + 'a,
1460 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1461 ) -> M
1462 where
1463 M: Monoid + 'a,
1464 FnBrand: CloneableFn + 'a, {
1465 func(fa.0)
1466 }
1467 }
1468
1469 #[document_type_parameters("The type of the second value in the pair.")]
1470 impl<Second: Clone + 'static> Traversable for PairSecondAppliedBrand<Second> {
1471 #[document_signature]
1475 #[document_type_parameters(
1477 "The lifetime of the values.",
1478 "The type of the elements in the traversable structure.",
1479 "The type of the elements in the resulting traversable structure.",
1480 "The applicative context."
1481 )]
1482 #[document_parameters("The function to apply.", "The result to traverse.")]
1484 #[document_returns("The result wrapped in the applicative context.")]
1486 #[document_examples]
1488 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1502 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1503 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1504 ) -> 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>)>)
1505 where
1506 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1507 let Pair(first, second) = ta;
1508 F::map(move |b| Pair(b, second.clone()), func(first))
1509 }
1510
1511 #[document_signature]
1515 #[document_type_parameters(
1517 "The lifetime of the values.",
1518 "The type of the elements in the traversable structure.",
1519 "The applicative context."
1520 )]
1521 #[document_parameters("The result containing the applicative value.")]
1523 #[document_returns("The result wrapped in the applicative context.")]
1525 #[document_examples]
1527 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1541 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>)>)
1542 ) -> 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>)>)
1543 where
1544 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1545 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1546 let Pair(first, second) = ta;
1547 F::map(move |a| Pair(a, second.clone()), first)
1548 }
1549 }
1550}
1551pub use inner::*;
1552
1553#[cfg(test)]
1554mod tests {
1555 use {
1556 super::inner::*,
1557 crate::{
1558 brands::*,
1559 classes::{
1560 CloneableFn,
1561 bifunctor::*,
1562 },
1563 functions::*,
1564 },
1565 quickcheck_macros::quickcheck,
1566 };
1567
1568 #[test]
1572 fn test_bimap() {
1573 let x = Pair(1, 5);
1574 assert_eq!(bimap::<PairBrand, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1575 }
1576
1577 #[quickcheck]
1581 fn bifunctor_identity(
1582 first: String,
1583 second: i32,
1584 ) -> bool {
1585 let x = Pair(first, second);
1586 bimap::<PairBrand, _, _, _, _>(identity, identity, x.clone()) == x
1587 }
1588
1589 #[quickcheck]
1591 fn bifunctor_composition(
1592 first: i32,
1593 second: i32,
1594 ) -> bool {
1595 let x = Pair(first, second);
1596 let f = |x: i32| x.wrapping_add(1);
1597 let g = |x: i32| x.wrapping_mul(2);
1598 let h = |x: i32| x.wrapping_sub(1);
1599 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1600
1601 bimap::<PairBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1602 == bimap::<PairBrand, _, _, _, _>(f, h, bimap::<PairBrand, _, _, _, _>(g, i, x))
1603 }
1604
1605 #[quickcheck]
1609 fn functor_identity(
1610 first: String,
1611 second: i32,
1612 ) -> bool {
1613 let x = Pair(first, second);
1614 map::<PairFirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1615 }
1616
1617 #[quickcheck]
1619 fn functor_composition(
1620 first: String,
1621 second: i32,
1622 ) -> bool {
1623 let x = Pair(first, second);
1624 let f = |x: i32| x.wrapping_add(1);
1625 let g = |x: i32| x.wrapping_mul(2);
1626 map::<PairFirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1627 == map::<PairFirstAppliedBrand<String>, _, _>(
1628 f,
1629 map::<PairFirstAppliedBrand<String>, _, _>(g, x),
1630 )
1631 }
1632
1633 #[quickcheck]
1637 fn applicative_identity(
1638 first: String,
1639 second: i32,
1640 ) -> bool {
1641 let v = Pair(first, second);
1642 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1643 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1644 v.clone(),
1645 ) == v
1646 }
1647
1648 #[quickcheck]
1650 fn applicative_homomorphism(x: i32) -> bool {
1651 let f = |x: i32| x.wrapping_mul(2);
1652 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1653 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1654 pure::<PairFirstAppliedBrand<String>, _>(x),
1655 ) == pure::<PairFirstAppliedBrand<String>, _>(f(x))
1656 }
1657
1658 #[quickcheck]
1660 fn applicative_composition(
1661 w_first: String,
1662 w_second: i32,
1663 u_seed: i32,
1664 v_seed: i32,
1665 ) -> bool {
1666 let w = Pair(w_first, w_second);
1667
1668 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1669 let u = pure::<PairFirstAppliedBrand<String>, _>(u_fn);
1670
1671 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1672 let v = pure::<PairFirstAppliedBrand<String>, _>(v_fn);
1673
1674 let vw = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1676 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u.clone(), vw);
1677
1678 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1680 let f = f.clone();
1681 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1682 let f = f.clone();
1683 let g = g.clone();
1684 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1685 })
1686 });
1687
1688 let pure_compose = pure::<PairFirstAppliedBrand<String>, _>(compose_fn);
1689 let u_applied = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(pure_compose, u);
1690 let uv = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u_applied, v);
1691 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(uv, w);
1692
1693 lhs == rhs
1694 }
1695
1696 #[quickcheck]
1698 fn applicative_interchange(
1699 y: i32,
1700 u_seed: i32,
1701 ) -> bool {
1702 let f = move |x: i32| x.wrapping_mul(u_seed);
1704 let u = pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1705
1706 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1707 u.clone(),
1708 pure::<PairFirstAppliedBrand<String>, _>(y),
1709 );
1710
1711 let rhs_fn =
1712 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1713 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1714 pure::<PairFirstAppliedBrand<String>, _>(rhs_fn),
1715 u,
1716 );
1717
1718 lhs == rhs
1719 }
1720
1721 #[quickcheck]
1725 fn monad_left_identity(a: i32) -> bool {
1726 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1727 bind::<PairFirstAppliedBrand<String>, _, _>(pure::<PairFirstAppliedBrand<String>, _>(a), f)
1728 == f(a)
1729 }
1730
1731 #[quickcheck]
1733 fn monad_right_identity(
1734 first: String,
1735 second: i32,
1736 ) -> bool {
1737 let m = Pair(first, second);
1738 bind::<PairFirstAppliedBrand<String>, _, _>(
1739 m.clone(),
1740 pure::<PairFirstAppliedBrand<String>, _>,
1741 ) == m
1742 }
1743
1744 #[quickcheck]
1746 fn monad_associativity(
1747 first: String,
1748 second: i32,
1749 ) -> bool {
1750 let m = Pair(first, second);
1751 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1752 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1753 bind::<PairFirstAppliedBrand<String>, _, _>(
1754 bind::<PairFirstAppliedBrand<String>, _, _>(m.clone(), f),
1755 g,
1756 ) == bind::<PairFirstAppliedBrand<String>, _, _>(m, |x| {
1757 bind::<PairFirstAppliedBrand<String>, _, _>(f(x), g)
1758 })
1759 }
1760}