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 #[document_fields("The first value.", "The second value.")]
56 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
59 pub struct Pair<First, Second>(pub First, pub Second);
60
61 impl_kind! {
62 for PairBrand {
63 type Of<First,Second> = Pair<First, Second>;
64 }
65 }
66
67 impl_kind! {
68 for PairBrand {
69 type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
70 }
71 }
72
73 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
74 #[document_parameters("The pair instance.")]
75 impl<First, Second> Pair<First, Second> {
76 #[document_signature]
80 #[document_type_parameters(
82 "The type of the mapped first value.",
83 "The type of the mapped second value."
84 )]
85 #[document_parameters(
87 "The function to apply to the first value.",
88 "The function to apply to the second value."
89 )]
90 #[document_returns("A new pair containing the mapped values.")]
92 #[document_examples]
94 pub fn bimap<B, D>(
102 self,
103 f: impl FnOnce(First) -> B,
104 g: impl FnOnce(Second) -> D,
105 ) -> Pair<B, D> {
106 Pair(f(self.0), g(self.1))
107 }
108
109 #[document_signature]
113 #[document_type_parameters("The type of the mapped first value.")]
115 #[document_parameters("The function to apply to the first value.")]
117 #[document_returns("A new pair with the transformed first value.")]
119 #[document_examples]
121 pub fn map_first<B>(
129 self,
130 f: impl FnOnce(First) -> B,
131 ) -> Pair<B, Second> {
132 Pair(f(self.0), self.1)
133 }
134
135 #[document_signature]
139 #[document_type_parameters("The type of the mapped second value.")]
141 #[document_parameters("The function to apply to the second value.")]
143 #[document_returns("A new pair with the transformed second value.")]
145 #[document_examples]
147 pub fn map_second<D>(
155 self,
156 g: impl FnOnce(Second) -> D,
157 ) -> Pair<First, D> {
158 Pair(self.0, g(self.1))
159 }
160
161 #[document_signature]
166 #[document_type_parameters("The result type.")]
168 #[document_parameters(
170 "The function to apply to the first value.",
171 "The function to apply to the second value.",
172 "The function to combine the results."
173 )]
174 #[document_returns("The combined result.")]
176 #[document_examples]
178 pub fn fold<C>(
187 self,
188 f: impl FnOnce(First) -> C,
189 g: impl FnOnce(Second) -> C,
190 combine: impl FnOnce(C, C) -> C,
191 ) -> C {
192 combine(f(self.0), g(self.1))
193 }
194
195 #[document_signature]
199 #[document_type_parameters("The accumulator type.")]
201 #[document_parameters(
203 "The step function for the first value.",
204 "The step function for the second value.",
205 "The initial accumulator."
206 )]
207 #[document_returns("The result of folding: `f(first, g(second, z))`.")]
209 #[document_examples]
211 pub fn bi_fold_right<C>(
219 self,
220 f: impl FnOnce(First, C) -> C,
221 g: impl FnOnce(Second, C) -> C,
222 z: C,
223 ) -> C {
224 f(self.0, g(self.1, z))
225 }
226
227 #[document_signature]
231 #[document_type_parameters("The accumulator type.")]
233 #[document_parameters(
235 "The step function for the first value.",
236 "The step function for the second value.",
237 "The initial accumulator."
238 )]
239 #[document_returns("The result of folding: `g(f(z, first), second)`.")]
241 #[document_examples]
243 pub fn bi_fold_left<C>(
251 self,
252 f: impl FnOnce(C, First) -> C,
253 g: impl FnOnce(C, Second) -> C,
254 z: C,
255 ) -> C {
256 g(f(z, self.0), self.1)
257 }
258
259 #[document_signature]
263 #[document_type_parameters("The monoid type.")]
265 #[document_parameters(
267 "The function mapping the first value to the monoid.",
268 "The function mapping the second value to the monoid."
269 )]
270 #[document_returns("The combined monoid value.")]
272 #[document_examples]
274 pub fn bi_fold_map<M: Semigroup>(
282 self,
283 f: impl FnOnce(First) -> M,
284 g: impl FnOnce(Second) -> M,
285 ) -> M {
286 Semigroup::append(f(self.0), g(self.1))
287 }
288 }
289
290 #[document_type_parameters(
291 "The lifetime of the values.",
292 "The type of the first value.",
293 "The type of the second value."
294 )]
295 #[document_parameters("The pair instance.")]
296 impl<'a, First: 'a, Second: 'a> Pair<First, Second> {
297 #[document_signature]
301 #[document_type_parameters(
303 "The output type for the first value.",
304 "The output type for the second value.",
305 "The applicative context."
306 )]
307 #[document_parameters(
309 "The function for the first value.",
310 "The function for the second value."
311 )]
312 #[document_returns("A pair of the transformed values wrapped in the applicative context.")]
314 #[document_examples]
316 pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
328 self,
329 f: impl Fn(First) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
330 g: impl Fn(Second) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
331 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Pair<C, D>>)
332 where
333 Pair<C, D>: Clone, {
334 F::lift2(|c, d| Pair(c, d), f(self.0), g(self.1))
335 }
336 }
337
338 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
339 #[document_parameters("The pair instance.")]
340 impl<First: Semigroup, Second> Pair<First, Second> {
341 #[document_signature]
346 #[document_type_parameters("The type of the new second value.")]
348 #[document_parameters("The function to apply to the second value.")]
350 #[document_returns(
352 "A new pair where the first values are combined and the second value is transformed."
353 )]
354 #[document_examples]
356 pub fn bind<C>(
366 self,
367 f: impl FnOnce(Second) -> Pair<First, C>,
368 ) -> Pair<First, C> {
369 let Pair(first, second) = self;
370 let Pair(next_first, next_second) = f(second);
371 Pair(Semigroup::append(first, next_first), next_second)
372 }
373 }
374
375 #[document_type_parameters("The type of the first value.", "The type of the second value.")]
376 #[document_parameters("The pair instance.")]
377 impl<First, Second: Semigroup> Pair<First, Second> {
378 #[document_signature]
383 #[document_type_parameters("The type of the new first value.")]
385 #[document_parameters("The function to apply to the first value.")]
387 #[document_returns(
389 "A new pair where the first value is transformed and the second values are combined."
390 )]
391 #[document_examples]
393 pub fn bind_first<C>(
403 self,
404 f: impl FnOnce(First) -> Pair<C, Second>,
405 ) -> Pair<C, Second> {
406 let Pair(first, second) = self;
407 let Pair(next_first, next_second) = f(first);
408 Pair(next_first, Semigroup::append(second, next_second))
409 }
410 }
411
412 impl Bifunctor for PairBrand {
413 #[document_signature]
417 #[document_type_parameters(
419 "The lifetime of the values.",
420 "The type of the first value.",
421 "The type of the mapped first value.",
422 "The type of the second value.",
423 "The type of the mapped second value."
424 )]
425 #[document_parameters(
427 "The function to apply to the first value.",
428 "The function to apply to the second value.",
429 "The pair to map over."
430 )]
431 #[document_returns("A new pair containing the mapped values.")]
433 #[document_examples]
434 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
447 f: impl Fn(A) -> B + 'a,
448 g: impl Fn(C) -> D + 'a,
449 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
450 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
451 p.bimap(f, g)
452 }
453 }
454
455 impl Bifoldable for PairBrand {
456 #[document_signature]
460 #[document_type_parameters(
462 "The lifetime of the values.",
463 "The brand of the cloneable function to use.",
464 "The type of the first value.",
465 "The type of the second value.",
466 "The accumulator type."
467 )]
468 #[document_parameters(
470 "The step function for the first value.",
471 "The step function for the second value.",
472 "The initial accumulator.",
473 "The pair to fold."
474 )]
475 #[document_returns("`f(a, g(b, z))`.")]
477 #[document_examples]
478 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
493 f: impl Fn(A, C) -> C + 'a,
494 g: impl Fn(B, C) -> C + 'a,
495 z: C,
496 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
497 ) -> C {
498 p.bi_fold_right(f, g, z)
499 }
500
501 #[document_signature]
505 #[document_type_parameters(
507 "The lifetime of the values.",
508 "The brand of the cloneable function to use.",
509 "The type of the first value.",
510 "The type of the second value.",
511 "The accumulator type."
512 )]
513 #[document_parameters(
515 "The step function for the first value.",
516 "The step function for the second value.",
517 "The initial accumulator.",
518 "The pair to fold."
519 )]
520 #[document_returns("`g(f(z, a), b)`.")]
522 #[document_examples]
523 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
538 f: impl Fn(C, A) -> C + 'a,
539 g: impl Fn(C, B) -> C + 'a,
540 z: C,
541 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
542 ) -> C {
543 p.bi_fold_left(f, g, z)
544 }
545
546 #[document_signature]
550 #[document_type_parameters(
552 "The lifetime of the values.",
553 "The brand of the cloneable function to use.",
554 "The type of the first value.",
555 "The type of the second value.",
556 "The monoid type."
557 )]
558 #[document_parameters(
560 "The function mapping the first value to the monoid.",
561 "The function mapping the second value to the monoid.",
562 "The pair to fold."
563 )]
564 #[document_returns("`Semigroup::append(f(a), g(b))`.")]
566 #[document_examples]
567 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
585 f: impl Fn(A) -> M + 'a,
586 g: impl Fn(B) -> M + 'a,
587 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
588 ) -> M
589 where
590 M: Monoid + 'a, {
591 p.bi_fold_map(f, g)
592 }
593 }
594
595 impl Bitraversable for PairBrand {
596 #[document_signature]
601 #[document_type_parameters(
603 "The lifetime of the values.",
604 "The type of the first value.",
605 "The type of the second value.",
606 "The output type for the first value.",
607 "The output type for the second value.",
608 "The applicative context."
609 )]
610 #[document_parameters(
612 "The function applied to the first value.",
613 "The function applied to the second value.",
614 "The pair to traverse."
615 )]
616 #[document_returns("`lift2(Pair, f(a), g(b))`.")]
618 #[document_examples]
619 fn bi_traverse<
638 'a,
639 A: 'a + Clone,
640 B: 'a + Clone,
641 C: 'a + Clone,
642 D: 'a + Clone,
643 F: Applicative,
644 >(
645 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
646 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
647 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
648 ) -> 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>)>)
649 {
650 p.bi_traverse::<C, D, F>(f, g)
651 }
652 }
653
654 impl_kind! {
657 #[document_type_parameters("The type of the first value in the pair.")]
658 impl<First: 'static> for PairFirstAppliedBrand<First> {
659 type Of<'a, A: 'a>: 'a = Pair<First, A>;
660 }
661 }
662
663 #[document_type_parameters("The type of the first value in the pair.")]
664 impl<First: 'static> Functor for PairFirstAppliedBrand<First> {
665 #[document_signature]
669 #[document_type_parameters(
671 "The lifetime of the values.",
672 "The type of the second value.",
673 "The type of the result of applying the function."
674 )]
675 #[document_parameters(
677 "The function to apply to the second value.",
678 "The pair to map over."
679 )]
680 #[document_returns(
682 "A new pair containing the result of applying the function to the second value."
683 )]
684 #[document_examples]
685 fn map<'a, A: 'a, B: 'a>(
696 func: impl Fn(A) -> B + 'a,
697 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
698 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
699 fa.map_second(func)
700 }
701 }
702
703 #[document_type_parameters("The type of the first value in the pair.")]
704 impl<First: Clone + 'static> Lift for PairFirstAppliedBrand<First>
705 where
706 First: Semigroup,
707 {
708 #[document_signature]
712 #[document_type_parameters(
714 "The lifetime of the values.",
715 "The type of the first second value.",
716 "The type of the second second value.",
717 "The type of the result second value."
718 )]
719 #[document_parameters(
721 "The binary function to apply to the second values.",
722 "The first pair.",
723 "The second pair."
724 )]
725 #[document_returns(
727 "A new pair where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
728 )]
729 #[document_examples]
730 fn lift2<'a, A, B, C>(
748 func: impl Fn(A, B) -> C + 'a,
749 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
750 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
751 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
752 where
753 A: Clone + 'a,
754 B: Clone + 'a,
755 C: 'a, {
756 let Pair(fa_first, fa_second) = fa;
757 let Pair(fb_first, fb_second) = fb;
758 Pair(Semigroup::append(fa_first, fb_first), func(fa_second, fb_second))
759 }
760 }
761
762 #[document_type_parameters("The type of the first value in the pair.")]
763 impl<First: Clone + 'static> Pointed for PairFirstAppliedBrand<First>
764 where
765 First: Monoid,
766 {
767 #[document_signature]
771 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
773 #[document_parameters("The value to wrap.")]
775 #[document_returns("A pair containing the empty value of the first type and `a`.")]
777 #[document_examples]
779 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
790 Pair(Monoid::empty(), a)
791 }
792 }
793
794 #[document_type_parameters("The type of the first value in the pair.")]
795 impl<First: Clone + Semigroup + 'static> ApplyFirst for PairFirstAppliedBrand<First> {}
796
797 #[document_type_parameters("The type of the first value in the pair.")]
798 impl<First: Clone + Semigroup + 'static> ApplySecond for PairFirstAppliedBrand<First> {}
799
800 #[document_type_parameters("The type of the first value in the pair.")]
801 impl<First: Clone + 'static> Semiapplicative for PairFirstAppliedBrand<First>
802 where
803 First: Semigroup,
804 {
805 #[document_signature]
809 #[document_type_parameters(
811 "The lifetime of the values.",
812 "The brand of the cloneable function wrapper.",
813 "The type of the input value.",
814 "The type of the output value."
815 )]
816 #[document_parameters(
818 "The pair containing the function.",
819 "The pair containing the value."
820 )]
821 #[document_returns(
823 "A new pair where the first values are combined and the function is applied to the second value."
824 )]
825 #[document_examples]
826 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
841 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
842 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
843 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
844 Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
845 }
846 }
847
848 #[document_type_parameters("The type of the first value in the pair.")]
849 impl<First: Clone + 'static> Semimonad for PairFirstAppliedBrand<First>
850 where
851 First: Semigroup,
852 {
853 #[document_signature]
857 #[document_type_parameters(
859 "The lifetime of the values.",
860 "The type of the result of the first computation.",
861 "The type of the result of the second computation."
862 )]
863 #[document_parameters("The first pair.", "The function to apply to the second value.")]
865 #[document_returns("A new pair where the first values are combined.")]
867 #[document_examples]
869 fn bind<'a, A: 'a, B: 'a>(
886 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
887 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
888 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
889 ma.bind(func)
890 }
891 }
892
893 #[document_type_parameters("The type of the first value in the pair.")]
894 impl<First: 'static> Foldable for PairFirstAppliedBrand<First> {
895 #[document_signature]
899 #[document_type_parameters(
901 "The lifetime of the values.",
902 "The brand of the cloneable function to use.",
903 "The type of the elements in the structure.",
904 "The type of the accumulator."
905 )]
906 #[document_parameters("The folding function.", "The initial value.", "The pair to fold.")]
908 #[document_returns("`func(a, initial)`.")]
910 #[document_examples]
912 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
926 func: impl Fn(A, B) -> B + 'a,
927 initial: B,
928 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
929 ) -> B
930 where
931 FnBrand: CloneableFn + 'a, {
932 func(fa.1, initial)
933 }
934
935 #[document_signature]
939 #[document_type_parameters(
941 "The lifetime of the values.",
942 "The brand of the cloneable function to use.",
943 "The type of the elements in the structure.",
944 "The type of the accumulator."
945 )]
946 #[document_parameters(
948 "The function to apply to the accumulator and each element.",
949 "The initial value of the accumulator.",
950 "The identity to fold."
951 )]
952 #[document_returns("`func(initial, a)`.")]
954 #[document_examples]
955 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
969 func: impl Fn(B, A) -> B + 'a,
970 initial: B,
971 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
972 ) -> B
973 where
974 FnBrand: CloneableFn + 'a, {
975 func(initial, fa.1)
976 }
977
978 #[document_signature]
982 #[document_type_parameters(
984 "The lifetime of the values.",
985 "The brand of the cloneable function to use.",
986 "The type of the elements in the structure.",
987 "The type of the monoid."
988 )]
989 #[document_parameters("The mapping function.", "The pair to fold.")]
991 #[document_returns("`func(a)`.")]
993 #[document_examples]
995 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1009 func: impl Fn(A) -> M + 'a,
1010 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1011 ) -> M
1012 where
1013 M: Monoid + 'a,
1014 FnBrand: CloneableFn + 'a, {
1015 func(fa.1)
1016 }
1017 }
1018
1019 #[document_type_parameters("The type of the first value in the pair.")]
1020 impl<First: Clone + 'static> Traversable for PairFirstAppliedBrand<First> {
1021 #[document_signature]
1025 #[document_type_parameters(
1027 "The lifetime of the values.",
1028 "The type of the elements in the traversable structure.",
1029 "The type of the elements in the resulting traversable structure.",
1030 "The applicative context."
1031 )]
1032 #[document_parameters(
1034 "The function to apply to each element, returning a value in an applicative context.",
1035 "The pair to traverse."
1036 )]
1037 #[document_returns("The pair wrapped in the applicative context.")]
1039 #[document_examples]
1040 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1054 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1055 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1056 ) -> 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>)>)
1057 where
1058 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1059 let Pair(first, second) = ta;
1060 F::map(move |b| Pair(first.clone(), b), func(second))
1061 }
1062
1063 #[document_signature]
1067 #[document_type_parameters(
1069 "The lifetime of the values.",
1070 "The type of the elements in the traversable structure.",
1071 "The applicative context."
1072 )]
1073 #[document_parameters("The pair containing the applicative value.")]
1075 #[document_returns("The pair wrapped in the applicative context.")]
1077 #[document_examples]
1079 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1093 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>)>)
1094 ) -> 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>)>)
1095 where
1096 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1097 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1098 let Pair(first, second) = ta;
1099 F::map(move |a| Pair(first.clone(), a), second)
1100 }
1101 }
1102
1103 impl_kind! {
1106 #[document_type_parameters("The type of the second value in the pair.")]
1107 impl<Second: 'static> for PairSecondAppliedBrand<Second> {
1108 type Of<'a, A: 'a>: 'a = Pair<A, Second>;
1109 }
1110 }
1111
1112 #[document_type_parameters("The type of the second value in the pair.")]
1113 impl<Second: 'static> Functor for PairSecondAppliedBrand<Second> {
1114 #[document_signature]
1118 #[document_type_parameters(
1120 "The lifetime of the values.",
1121 "The type of the first value.",
1122 "The type of the result of applying the function."
1123 )]
1124 #[document_parameters("The function to apply to the first value.", "The pair to map over.")]
1126 #[document_returns(
1128 "A new pair containing the result of applying the function to the first value."
1129 )]
1130 #[document_examples]
1132 fn map<'a, A: 'a, B: 'a>(
1143 func: impl Fn(A) -> B + 'a,
1144 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1145 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1146 fa.map_first(func)
1147 }
1148 }
1149
1150 #[document_type_parameters("The type of the second value in the pair.")]
1151 impl<Second: Clone + 'static> Lift for PairSecondAppliedBrand<Second>
1152 where
1153 Second: Semigroup,
1154 {
1155 #[document_signature]
1159 #[document_type_parameters(
1161 "The lifetime of the values.",
1162 "The type of the first first value.",
1163 "The type of the second first value.",
1164 "The type of the result first value."
1165 )]
1166 #[document_parameters(
1168 "The binary function to apply to the first values.",
1169 "The first pair.",
1170 "The second pair."
1171 )]
1172 #[document_returns(
1174 "A new pair where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
1175 )]
1176 #[document_examples]
1177 fn lift2<'a, A, B, C>(
1195 func: impl Fn(A, B) -> C + 'a,
1196 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1197 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1198 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1199 where
1200 A: Clone + 'a,
1201 B: Clone + 'a,
1202 C: 'a, {
1203 Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
1204 }
1205 }
1206
1207 #[document_type_parameters("The type of the second value in the pair.")]
1208 impl<Second: Clone + 'static> Pointed for PairSecondAppliedBrand<Second>
1209 where
1210 Second: Monoid,
1211 {
1212 #[document_signature]
1216 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1218 #[document_parameters("The value to wrap.")]
1220 #[document_returns("A pair containing `a` and the empty value of the second type.")]
1222 #[document_examples]
1224 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1235 Pair(a, Monoid::empty())
1236 }
1237 }
1238
1239 #[document_type_parameters("The type of the second value in the pair.")]
1240 impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairSecondAppliedBrand<Second> {}
1241
1242 #[document_type_parameters("The type of the second value in the pair.")]
1243 impl<Second: Clone + Semigroup + 'static> ApplySecond for PairSecondAppliedBrand<Second> {}
1244
1245 #[document_type_parameters("The type of the second value in the pair.")]
1246 impl<Second: Clone + 'static> Semiapplicative for PairSecondAppliedBrand<Second>
1247 where
1248 Second: Semigroup,
1249 {
1250 #[document_signature]
1254 #[document_type_parameters(
1256 "The lifetime of the values.",
1257 "The brand of the cloneable function wrapper.",
1258 "The type of the input value.",
1259 "The type of the output value."
1260 )]
1261 #[document_parameters(
1263 "The pair containing the function (in Err).",
1264 "The pair containing the value (in Err)."
1265 )]
1266 #[document_returns(
1268 "`Err(f(a))` if both are `Err`, otherwise the first success encountered."
1269 )]
1270 #[document_examples]
1271 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1286 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1287 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1288 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1289 Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1290 }
1291 }
1292
1293 #[document_type_parameters("The type of the second value in the pair.")]
1294 impl<Second: Clone + 'static> Semimonad for PairSecondAppliedBrand<Second>
1295 where
1296 Second: Semigroup,
1297 {
1298 #[document_signature]
1302 #[document_type_parameters(
1304 "The lifetime of the values.",
1305 "The type of the result of the first computation.",
1306 "The type of the result of the second computation."
1307 )]
1308 #[document_parameters("The first result.", "The function to apply to the error value.")]
1310 #[document_returns(
1312 "The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
1313 )]
1314 #[document_examples]
1316 fn bind<'a, A: 'a, B: 'a>(
1333 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1334 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1335 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1336 ma.bind_first(func)
1337 }
1338 }
1339
1340 #[document_type_parameters("The type of the second value in the pair.")]
1341 impl<Second: 'static> Foldable for PairSecondAppliedBrand<Second> {
1342 #[document_signature]
1346 #[document_type_parameters(
1348 "The lifetime of the values.",
1349 "The brand of the cloneable function to use.",
1350 "The type of the elements in the structure.",
1351 "The type of the accumulator."
1352 )]
1353 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1355 #[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
1357 #[document_examples]
1359 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1373 func: impl Fn(A, B) -> B + 'a,
1374 initial: B,
1375 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1376 ) -> B
1377 where
1378 FnBrand: CloneableFn + 'a, {
1379 func(fa.0, initial)
1380 }
1381
1382 #[document_signature]
1386 #[document_type_parameters(
1388 "The lifetime of the values.",
1389 "The brand of the cloneable function to use.",
1390 "The type of the elements in the structure.",
1391 "The type of the accumulator."
1392 )]
1393 #[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1395 #[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
1397 #[document_examples]
1399 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1413 func: impl Fn(B, A) -> B + 'a,
1414 initial: B,
1415 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1416 ) -> B
1417 where
1418 FnBrand: CloneableFn + 'a, {
1419 func(initial, fa.0)
1420 }
1421
1422 #[document_signature]
1426 #[document_type_parameters(
1428 "The lifetime of the values.",
1429 "The brand of the cloneable function to use.",
1430 "The type of the elements in the structure.",
1431 "The type of the monoid."
1432 )]
1433 #[document_parameters("The mapping function.", "The result to fold.")]
1435 #[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
1437 #[document_examples]
1439 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1456 func: impl Fn(A) -> M + 'a,
1457 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1458 ) -> M
1459 where
1460 M: Monoid + 'a,
1461 FnBrand: CloneableFn + 'a, {
1462 func(fa.0)
1463 }
1464 }
1465
1466 #[document_type_parameters("The type of the second value in the pair.")]
1467 impl<Second: Clone + 'static> Traversable for PairSecondAppliedBrand<Second> {
1468 #[document_signature]
1472 #[document_type_parameters(
1474 "The lifetime of the values.",
1475 "The type of the elements in the traversable structure.",
1476 "The type of the elements in the resulting traversable structure.",
1477 "The applicative context."
1478 )]
1479 #[document_parameters("The function to apply.", "The result to traverse.")]
1481 #[document_returns("The result wrapped in the applicative context.")]
1483 #[document_examples]
1485 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1499 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1500 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1501 ) -> 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>)>)
1502 where
1503 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1504 let Pair(first, second) = ta;
1505 F::map(move |b| Pair(b, second.clone()), func(first))
1506 }
1507
1508 #[document_signature]
1512 #[document_type_parameters(
1514 "The lifetime of the values.",
1515 "The type of the elements in the traversable structure.",
1516 "The applicative context."
1517 )]
1518 #[document_parameters("The result containing the applicative value.")]
1520 #[document_returns("The result wrapped in the applicative context.")]
1522 #[document_examples]
1524 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1538 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>)>)
1539 ) -> 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>)>)
1540 where
1541 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1542 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1543 let Pair(first, second) = ta;
1544 F::map(move |a| Pair(a, second.clone()), first)
1545 }
1546 }
1547}
1548pub use inner::*;
1549
1550#[cfg(test)]
1551mod tests {
1552 use {
1553 super::inner::*,
1554 crate::{
1555 brands::*,
1556 classes::{
1557 CloneableFn,
1558 bifunctor::*,
1559 },
1560 functions::*,
1561 },
1562 quickcheck_macros::quickcheck,
1563 };
1564
1565 #[test]
1569 fn test_bimap() {
1570 let x = Pair(1, 5);
1571 assert_eq!(bimap::<PairBrand, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1572 }
1573
1574 #[quickcheck]
1578 fn bifunctor_identity(
1579 first: String,
1580 second: i32,
1581 ) -> bool {
1582 let x = Pair(first, second);
1583 bimap::<PairBrand, _, _, _, _>(identity, identity, x.clone()) == x
1584 }
1585
1586 #[quickcheck]
1588 fn bifunctor_composition(
1589 first: i32,
1590 second: i32,
1591 ) -> bool {
1592 let x = Pair(first, second);
1593 let f = |x: i32| x.wrapping_add(1);
1594 let g = |x: i32| x.wrapping_mul(2);
1595 let h = |x: i32| x.wrapping_sub(1);
1596 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1597
1598 bimap::<PairBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1599 == bimap::<PairBrand, _, _, _, _>(f, h, bimap::<PairBrand, _, _, _, _>(g, i, x))
1600 }
1601
1602 #[quickcheck]
1606 fn functor_identity(
1607 first: String,
1608 second: i32,
1609 ) -> bool {
1610 let x = Pair(first, second);
1611 map::<PairFirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1612 }
1613
1614 #[quickcheck]
1616 fn functor_composition(
1617 first: String,
1618 second: i32,
1619 ) -> bool {
1620 let x = Pair(first, second);
1621 let f = |x: i32| x.wrapping_add(1);
1622 let g = |x: i32| x.wrapping_mul(2);
1623 map::<PairFirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1624 == map::<PairFirstAppliedBrand<String>, _, _>(
1625 f,
1626 map::<PairFirstAppliedBrand<String>, _, _>(g, x),
1627 )
1628 }
1629
1630 #[quickcheck]
1634 fn applicative_identity(
1635 first: String,
1636 second: i32,
1637 ) -> bool {
1638 let v = Pair(first, second);
1639 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1640 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1641 v.clone(),
1642 ) == v
1643 }
1644
1645 #[quickcheck]
1647 fn applicative_homomorphism(x: i32) -> bool {
1648 let f = |x: i32| x.wrapping_mul(2);
1649 apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1650 pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1651 pure::<PairFirstAppliedBrand<String>, _>(x),
1652 ) == pure::<PairFirstAppliedBrand<String>, _>(f(x))
1653 }
1654
1655 #[quickcheck]
1657 fn applicative_composition(
1658 w_first: String,
1659 w_second: i32,
1660 u_seed: i32,
1661 v_seed: i32,
1662 ) -> bool {
1663 let w = Pair(w_first, w_second);
1664
1665 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1666 let u = pure::<PairFirstAppliedBrand<String>, _>(u_fn);
1667
1668 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1669 let v = pure::<PairFirstAppliedBrand<String>, _>(v_fn);
1670
1671 let vw = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1673 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u.clone(), vw);
1674
1675 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1677 let f = f.clone();
1678 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1679 let f = f.clone();
1680 let g = g.clone();
1681 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1682 })
1683 });
1684
1685 let pure_compose = pure::<PairFirstAppliedBrand<String>, _>(compose_fn);
1686 let u_applied = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(pure_compose, u);
1687 let uv = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u_applied, v);
1688 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(uv, w);
1689
1690 lhs == rhs
1691 }
1692
1693 #[quickcheck]
1695 fn applicative_interchange(
1696 y: i32,
1697 u_seed: i32,
1698 ) -> bool {
1699 let f = move |x: i32| x.wrapping_mul(u_seed);
1701 let u = pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1702
1703 let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1704 u.clone(),
1705 pure::<PairFirstAppliedBrand<String>, _>(y),
1706 );
1707
1708 let rhs_fn =
1709 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1710 let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1711 pure::<PairFirstAppliedBrand<String>, _>(rhs_fn),
1712 u,
1713 );
1714
1715 lhs == rhs
1716 }
1717
1718 #[quickcheck]
1722 fn monad_left_identity(a: i32) -> bool {
1723 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1724 bind::<PairFirstAppliedBrand<String>, _, _>(pure::<PairFirstAppliedBrand<String>, _>(a), f)
1725 == f(a)
1726 }
1727
1728 #[quickcheck]
1730 fn monad_right_identity(
1731 first: String,
1732 second: i32,
1733 ) -> bool {
1734 let m = Pair(first, second);
1735 bind::<PairFirstAppliedBrand<String>, _, _>(
1736 m.clone(),
1737 pure::<PairFirstAppliedBrand<String>, _>,
1738 ) == m
1739 }
1740
1741 #[quickcheck]
1743 fn monad_associativity(
1744 first: String,
1745 second: i32,
1746 ) -> bool {
1747 let m = Pair(first, second);
1748 let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1749 let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1750 bind::<PairFirstAppliedBrand<String>, _, _>(
1751 bind::<PairFirstAppliedBrand<String>, _, _>(m.clone(), f),
1752 g,
1753 ) == bind::<PairFirstAppliedBrand<String>, _, _>(m, |x| {
1754 bind::<PairFirstAppliedBrand<String>, _, _>(f(x), g)
1755 })
1756 }
1757}