1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::{
11 Tuple2Brand,
12 Tuple2FirstAppliedBrand,
13 Tuple2SecondAppliedBrand,
14 },
15 classes::{
16 Applicative,
17 ApplyFirst,
18 ApplySecond,
19 Bifoldable,
20 Bifunctor,
21 Bitraversable,
22 CloneableFn,
23 Foldable,
24 Functor,
25 Lift,
26 Monoid,
27 ParFoldable,
28 Pointed,
29 Semiapplicative,
30 Semigroup,
31 Semimonad,
32 SendCloneableFn,
33 Traversable,
34 },
35 impl_kind,
36 kinds::*,
37 },
38 fp_macros::*,
39 };
40
41 impl_kind! {
42 for Tuple2Brand {
43 type Of<First, Second> = (First, Second);
44 }
45 }
46
47 impl_kind! {
48 for Tuple2Brand {
49 type Of<'a, First: 'a, Second: 'a>: 'a = (First, Second);
50 }
51 }
52
53 impl Bifunctor for Tuple2Brand {
54 #[document_signature]
58 #[document_type_parameters(
60 "The lifetime of the values.",
61 "The type of the first value.",
62 "The type of the mapped first value.",
63 "The type of the second value.",
64 "The type of the mapped second value."
65 )]
66 #[document_parameters(
68 "The function to apply to the first value.",
69 "The function to apply to the second value.",
70 "The tuple to map over."
71 )]
72 #[document_returns("A new tuple containing the mapped values.")]
74 #[document_examples]
75 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
87 f: impl Fn(A) -> B + 'a,
88 g: impl Fn(C) -> D + 'a,
89 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
90 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
91 (f(p.0), g(p.1))
92 }
93 }
94
95 impl Bifoldable for Tuple2Brand {
96 #[document_signature]
101 #[document_type_parameters(
103 "The lifetime of the values.",
104 "The brand of the cloneable function to use.",
105 "The type of the first element.",
106 "The type of the second element.",
107 "The accumulator type."
108 )]
109 #[document_parameters(
111 "The step function applied to the first element.",
112 "The step function applied to the second element.",
113 "The initial accumulator.",
114 "The tuple to fold."
115 )]
116 #[document_returns("`f(a, g(b, z))`.")]
118 #[document_examples]
119 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
137 f: impl Fn(A, C) -> C + 'a,
138 g: impl Fn(B, C) -> C + 'a,
139 z: C,
140 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
141 ) -> C {
142 let (a, b) = p;
143 f(a, g(b, z))
144 }
145
146 #[document_signature]
151 #[document_type_parameters(
153 "The lifetime of the values.",
154 "The brand of the cloneable function to use.",
155 "The type of the first element.",
156 "The type of the second element.",
157 "The accumulator type."
158 )]
159 #[document_parameters(
161 "The step function applied to the first element.",
162 "The step function applied to the second element.",
163 "The initial accumulator.",
164 "The tuple to fold."
165 )]
166 #[document_returns("`g(f(z, a), b)`.")]
168 #[document_examples]
169 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
187 f: impl Fn(C, A) -> C + 'a,
188 g: impl Fn(C, B) -> C + 'a,
189 z: C,
190 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
191 ) -> C {
192 let (a, b) = p;
193 g(f(z, a), b)
194 }
195
196 #[document_signature]
200 #[document_type_parameters(
202 "The lifetime of the values.",
203 "The brand of the cloneable function to use.",
204 "The type of the first element.",
205 "The type of the second element.",
206 "The monoid type."
207 )]
208 #[document_parameters(
210 "The function mapping the first element to the monoid.",
211 "The function mapping the second element to the monoid.",
212 "The tuple to fold."
213 )]
214 #[document_returns("`M::append(f(a), g(b))`.")]
216 #[document_examples]
217 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
234 f: impl Fn(A) -> M + 'a,
235 g: impl Fn(B) -> M + 'a,
236 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
237 ) -> M
238 where
239 M: Monoid + 'a, {
240 let (a, b) = p;
241 M::append(f(a), g(b))
242 }
243 }
244
245 impl Bitraversable for Tuple2Brand {
246 #[document_signature]
251 #[document_type_parameters(
253 "The lifetime of the values.",
254 "The type of the first element.",
255 "The type of the second element.",
256 "The output type for the first element.",
257 "The output type for the second element.",
258 "The applicative context."
259 )]
260 #[document_parameters(
262 "The function applied to the first element.",
263 "The function applied to the second element.",
264 "The tuple to traverse."
265 )]
266 #[document_returns("`lift2(|c, d| (c, d), f(a), g(b))`.")]
268 #[document_examples]
269 fn bi_traverse<
286 'a,
287 A: 'a + Clone,
288 B: 'a + Clone,
289 C: 'a + Clone,
290 D: 'a + Clone,
291 F: Applicative,
292 >(
293 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
294 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
295 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
296 ) -> 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>)>)
297 {
298 let (a, b) = p;
299 F::lift2(|c, d| (c, d), f(a), g(b))
300 }
301 }
302
303 impl_kind! {
306 impl<First: 'static> for Tuple2FirstAppliedBrand<First> {
307 type Of<'a, A: 'a>: 'a = (First, A);
308 }
309 }
310
311 #[document_type_parameters("The type of the first value in the tuple.")]
312 impl<First: 'static> Functor for Tuple2FirstAppliedBrand<First> {
313 #[document_signature]
317 #[document_type_parameters(
319 "The lifetime of the values.",
320 "The type of the second value.",
321 "The type of the result of applying the function."
322 )]
323 #[document_parameters(
325 "The function to apply to the second value.",
326 "The tuple to map over."
327 )]
328 #[document_returns(
330 "A new tuple containing the result of applying the function to the second value."
331 )]
332 #[document_examples]
333 fn map<'a, A: 'a, B: 'a>(
343 func: impl Fn(A) -> B + 'a,
344 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
345 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
346 (fa.0, func(fa.1))
347 }
348 }
349
350 #[document_type_parameters("The type of the first value in the tuple.")]
351 impl<First: Clone + 'static> Lift for Tuple2FirstAppliedBrand<First>
352 where
353 First: Semigroup,
354 {
355 #[document_signature]
359 #[document_type_parameters(
361 "The lifetime of the values.",
362 "The type of the first second value.",
363 "The type of the second second value.",
364 "The type of the result second value."
365 )]
366 #[document_parameters(
368 "The binary function to apply to the second values.",
369 "The first tuple.",
370 "The second tuple."
371 )]
372 #[document_returns(
374 "A new tuple where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
375 )]
376 #[document_examples]
377 fn lift2<'a, A, B, C>(
394 func: impl Fn(A, B) -> C + 'a,
395 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
396 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
397 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
398 where
399 A: Clone + 'a,
400 B: Clone + 'a,
401 C: 'a, {
402 (Semigroup::append(fa.0, fb.0), func(fa.1, fb.1))
403 }
404 }
405
406 #[document_type_parameters("The type of the first value in the tuple.")]
407 impl<First: Clone + 'static> Pointed for Tuple2FirstAppliedBrand<First>
408 where
409 First: Monoid,
410 {
411 #[document_signature]
415 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
417 #[document_parameters("The value to wrap.")]
419 #[document_returns("A tuple containing the empty value of the first type and `a`.")]
421 #[document_examples]
423 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
433 (Monoid::empty(), a)
434 }
435 }
436
437 #[document_type_parameters("The type of the first value in the tuple.")]
438 impl<First: Clone + Semigroup + 'static> ApplyFirst for Tuple2FirstAppliedBrand<First> {}
439 #[document_type_parameters("The type of the first value in the tuple.")]
440 impl<First: Clone + Semigroup + 'static> ApplySecond for Tuple2FirstAppliedBrand<First> {}
441
442 #[document_type_parameters("The type of the first value in the tuple.")]
443 impl<First: Clone + 'static> Semiapplicative for Tuple2FirstAppliedBrand<First>
444 where
445 First: Semigroup,
446 {
447 #[document_signature]
451 #[document_type_parameters(
453 "The lifetime of the values.",
454 "The brand of the cloneable function wrapper.",
455 "The type of the input value.",
456 "The type of the output value."
457 )]
458 #[document_parameters(
460 "The tuple containing the function.",
461 "The tuple containing the value."
462 )]
463 #[document_returns(
465 "A new tuple where the first values are combined and the function is applied to the second value."
466 )]
467 #[document_examples]
468 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
482 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
483 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
484 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
485 (Semigroup::append(ff.0, fa.0), ff.1(fa.1))
486 }
487 }
488
489 #[document_type_parameters("The type of the first value in the tuple.")]
490 impl<First: Clone + 'static> Semimonad for Tuple2FirstAppliedBrand<First>
491 where
492 First: Semigroup,
493 {
494 #[document_signature]
498 #[document_type_parameters(
500 "The lifetime of the values.",
501 "The type of the result of the first computation.",
502 "The type of the result of the second computation."
503 )]
504 #[document_parameters("The first tuple.", "The function to apply to the second value.")]
506 #[document_returns("A new tuple where the first values are combined.")]
508 #[document_examples]
510 fn bind<'a, A: 'a, B: 'a>(
526 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
527 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
528 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
529 let (first, second) = ma;
530 let (next_first, next_second) = func(second);
531 (Semigroup::append(first, next_first), next_second)
532 }
533 }
534
535 #[document_type_parameters("The type of the first value in the tuple.")]
536 impl<First: 'static> Foldable for Tuple2FirstAppliedBrand<First> {
537 #[document_signature]
541 #[document_type_parameters(
543 "The lifetime of the values.",
544 "The brand of the cloneable function to use.",
545 "The type of the elements in the structure.",
546 "The type of the accumulator."
547 )]
548 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
550 #[document_returns("`func(a, initial)`.")]
552 #[document_examples]
554 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
567 func: impl Fn(A, B) -> B + 'a,
568 initial: B,
569 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
570 ) -> B
571 where
572 FnBrand: CloneableFn + 'a, {
573 func(fa.1, initial)
574 }
575
576 #[document_signature]
580 #[document_type_parameters(
582 "The lifetime of the values.",
583 "The brand of the cloneable function to use.",
584 "The type of the elements in the structure.",
585 "The type of the accumulator."
586 )]
587 #[document_parameters(
589 "The function to apply to the accumulator and each element.",
590 "The initial value of the accumulator.",
591 "The tuple to fold."
592 )]
593 #[document_returns("`func(initial, a)`.")]
595 #[document_examples]
596 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
609 func: impl Fn(B, A) -> B + 'a,
610 initial: B,
611 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
612 ) -> B
613 where
614 FnBrand: CloneableFn + 'a, {
615 func(initial, fa.1)
616 }
617
618 #[document_signature]
622 #[document_type_parameters(
624 "The lifetime of the values.",
625 "The brand of the cloneable function to use.",
626 "The type of the elements in the structure.",
627 "The type of the monoid."
628 )]
629 #[document_parameters("The mapping function.", "The tuple to fold.")]
631 #[document_returns("`func(a)`.")]
633 #[document_examples]
635 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
648 func: impl Fn(A) -> M + 'a,
649 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
650 ) -> M
651 where
652 M: Monoid + 'a,
653 FnBrand: CloneableFn + 'a, {
654 func(fa.1)
655 }
656 }
657
658 #[document_type_parameters("The type of the first value in the tuple.")]
659 impl<First: Clone + 'static> Traversable for Tuple2FirstAppliedBrand<First> {
660 #[document_signature]
664 #[document_type_parameters(
666 "The lifetime of the values.",
667 "The type of the elements in the traversable structure.",
668 "The type of the elements in the resulting traversable structure.",
669 "The applicative context."
670 )]
671 #[document_parameters(
673 "The function to apply to each element, returning a value in an applicative context.",
674 "The tuple to traverse."
675 )]
676 #[document_returns("The tuple wrapped in the applicative context.")]
678 #[document_examples]
679 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
692 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
693 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
694 ) -> 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>)>)
695 where
696 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
697 let (first, second) = ta;
698 F::map(move |b| (first.clone(), b), func(second))
699 }
700
701 #[document_signature]
705 #[document_type_parameters(
707 "The lifetime of the values.",
708 "The type of the elements in the traversable structure.",
709 "The applicative context."
710 )]
711 #[document_parameters("The tuple containing the applicative value.")]
713 #[document_returns("The tuple wrapped in the applicative context.")]
715 #[document_examples]
717 fn sequence<'a, A: 'a + Clone, F: Applicative>(
730 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>)>)
731 ) -> 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>)>)
732 where
733 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
734 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
735 let (first, second) = ta;
736 F::map(move |a| (first.clone(), a), second)
737 }
738 }
739
740 #[document_type_parameters("The type of the first value in the tuple.")]
741 impl<First: 'static> ParFoldable for Tuple2FirstAppliedBrand<First> {
742 #[document_signature]
746 #[document_type_parameters(
748 "The lifetime of the values.",
749 "The brand of the cloneable function wrapper.",
750 "The element type.",
751 "The monoid type."
752 )]
753 #[document_parameters(
755 "The thread-safe function to map each element to a monoid.",
756 "The tuple to fold."
757 )]
758 #[document_returns("The combined monoid value.")]
760 #[document_examples]
761 fn par_fold_map<'a, FnBrand, A, M>(
776 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
777 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
778 ) -> M
779 where
780 FnBrand: 'a + SendCloneableFn,
781 A: 'a + Clone + Send + Sync,
782 M: Monoid + Send + Sync + 'a, {
783 func(fa.1)
784 }
785
786 #[document_signature]
790 #[document_type_parameters(
792 "The lifetime of the values.",
793 "The brand of the cloneable function wrapper.",
794 "The element type.",
795 "The accumulator type."
796 )]
797 #[document_parameters(
799 "The thread-safe function to apply to each element and the accumulator.",
800 "The initial value.",
801 "The tuple to fold."
802 )]
803 #[document_returns("The final accumulator value.")]
805 #[document_examples]
806 fn par_fold_right<'a, FnBrand, A, B>(
818 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
819 initial: B,
820 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
821 ) -> B
822 where
823 FnBrand: 'a + SendCloneableFn,
824 A: 'a + Clone + Send + Sync,
825 B: Send + Sync + 'a, {
826 func((fa.1, initial))
827 }
828 }
829
830 impl_kind! {
833 impl<Second: 'static> for Tuple2SecondAppliedBrand<Second> {
834 type Of<'a, A: 'a>: 'a = (A, Second);
835 }
836 }
837
838 #[document_type_parameters("The type of the second value in the tuple.")]
839 impl<Second: 'static> Functor for Tuple2SecondAppliedBrand<Second> {
840 #[document_signature]
844 #[document_type_parameters(
846 "The lifetime of the values.",
847 "The type of the first value.",
848 "The type of the result of applying the function."
849 )]
850 #[document_parameters(
852 "The function to apply to the first value.",
853 "The tuple to map over."
854 )]
855 #[document_returns(
857 "A new tuple containing the result of applying the function to the first value."
858 )]
859 #[document_examples]
860 fn map<'a, A: 'a, B: 'a>(
870 func: impl Fn(A) -> B + 'a,
871 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
872 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
873 (func(fa.0), fa.1)
874 }
875 }
876
877 #[document_type_parameters("The type of the second value in the tuple.")]
878 impl<Second: Clone + 'static> Lift for Tuple2SecondAppliedBrand<Second>
879 where
880 Second: Semigroup,
881 {
882 #[document_signature]
886 #[document_type_parameters(
888 "The lifetime of the values.",
889 "The type of the first first value.",
890 "The type of the second first value.",
891 "The type of the result first value."
892 )]
893 #[document_parameters(
895 "The binary function to apply to the first values.",
896 "The first tuple.",
897 "The second tuple."
898 )]
899 #[document_returns(
901 "A new tuple where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
902 )]
903 #[document_examples]
904 fn lift2<'a, A, B, C>(
921 func: impl Fn(A, B) -> C + 'a,
922 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
923 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
924 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
925 where
926 A: Clone + 'a,
927 B: Clone + 'a,
928 C: 'a, {
929 (func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
930 }
931 }
932
933 #[document_type_parameters("The type of the second value in the tuple.")]
934 impl<Second: Clone + 'static> Pointed for Tuple2SecondAppliedBrand<Second>
935 where
936 Second: Monoid,
937 {
938 #[document_signature]
942 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
944 #[document_parameters("The value to wrap.")]
946 #[document_returns("A tuple containing `a` and the empty value of the second type.")]
948 #[document_examples]
950 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
960 (a, Monoid::empty())
961 }
962 }
963
964 #[document_type_parameters("The type of the second value in the tuple.")]
965 impl<Second: Clone + Semigroup + 'static> ApplyFirst for Tuple2SecondAppliedBrand<Second> {}
966 #[document_type_parameters("The type of the second value in the tuple.")]
967 impl<Second: Clone + Semigroup + 'static> ApplySecond for Tuple2SecondAppliedBrand<Second> {}
968
969 #[document_type_parameters("The type of the second value in the tuple.")]
970 impl<Second: Clone + 'static> Semiapplicative for Tuple2SecondAppliedBrand<Second>
971 where
972 Second: Semigroup,
973 {
974 #[document_signature]
978 #[document_type_parameters(
980 "The lifetime of the values.",
981 "The brand of the cloneable function wrapper.",
982 "The type of the input value.",
983 "The type of the output value."
984 )]
985 #[document_parameters(
987 "The tuple containing the function.",
988 "The tuple containing the value."
989 )]
990 #[document_returns(
992 "A new tuple where the function is applied to the first value and the second values are combined."
993 )]
994 #[document_examples]
995 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1009 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1010 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1011 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1012 (ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1013 }
1014 }
1015
1016 #[document_type_parameters("The type of the second value in the tuple.")]
1017 impl<Second: Clone + 'static> Semimonad for Tuple2SecondAppliedBrand<Second>
1018 where
1019 Second: Semigroup,
1020 {
1021 #[document_signature]
1025 #[document_type_parameters(
1027 "The lifetime of the values.",
1028 "The type of the result of the first computation.",
1029 "The type of the result of the second computation."
1030 )]
1031 #[document_parameters("The first tuple.", "The function to apply to the first value.")]
1033 #[document_returns("A new tuple where the second values are combined.")]
1035 #[document_examples]
1037 fn bind<'a, A: 'a, B: 'a>(
1053 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1054 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1055 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1056 let (first, second) = ma;
1057 let (next_first, next_second) = func(first);
1058 (next_first, Semigroup::append(second, next_second))
1059 }
1060 }
1061
1062 #[document_type_parameters("The type of the second value in the tuple.")]
1063 impl<Second: 'static> Foldable for Tuple2SecondAppliedBrand<Second> {
1064 #[document_signature]
1068 #[document_type_parameters(
1070 "The lifetime of the values.",
1071 "The brand of the cloneable function to use.",
1072 "The type of the elements in the structure.",
1073 "The type of the accumulator."
1074 )]
1075 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1077 #[document_returns("`func(a, initial)`.")]
1079 #[document_examples]
1081 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1094 func: impl Fn(A, B) -> B + 'a,
1095 initial: B,
1096 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1097 ) -> B
1098 where
1099 FnBrand: CloneableFn + 'a, {
1100 func(fa.0, initial)
1101 }
1102
1103 #[document_signature]
1107 #[document_type_parameters(
1109 "The lifetime of the values.",
1110 "The brand of the cloneable function to use.",
1111 "The type of the elements in the structure.",
1112 "The type of the accumulator."
1113 )]
1114 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1116 #[document_returns("`func(initial, a)`.")]
1118 #[document_examples]
1120 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1133 func: impl Fn(B, A) -> B + 'a,
1134 initial: B,
1135 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1136 ) -> B
1137 where
1138 FnBrand: CloneableFn + 'a, {
1139 func(initial, fa.0)
1140 }
1141
1142 #[document_signature]
1146 #[document_type_parameters(
1148 "The lifetime of the values.",
1149 "The brand of the cloneable function to use.",
1150 "The type of the elements in the structure.",
1151 "The type of the monoid."
1152 )]
1153 #[document_parameters("The mapping function.", "The tuple to fold.")]
1155 #[document_returns("`func(a)`.")]
1157 #[document_examples]
1159 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1172 func: impl Fn(A) -> M + 'a,
1173 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1174 ) -> M
1175 where
1176 M: Monoid + 'a,
1177 FnBrand: CloneableFn + 'a, {
1178 func(fa.0)
1179 }
1180 }
1181
1182 #[document_type_parameters("The type of the second value in the tuple.")]
1183 impl<Second: Clone + 'static> Traversable for Tuple2SecondAppliedBrand<Second> {
1184 #[document_signature]
1188 #[document_type_parameters(
1190 "The lifetime of the values.",
1191 "The type of the elements in the traversable structure.",
1192 "The type of the elements in the resulting traversable structure.",
1193 "The applicative context."
1194 )]
1195 #[document_parameters("The function to apply.", "The tuple to traverse.")]
1197 #[document_returns("The tuple wrapped in the applicative context.")]
1199 #[document_examples]
1201 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1214 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1215 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1216 ) -> 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>)>)
1217 where
1218 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1219 let (first, second) = ta;
1220 F::map(move |b| (b, second.clone()), func(first))
1221 }
1222
1223 #[document_signature]
1227 #[document_type_parameters(
1229 "The lifetime of the values.",
1230 "The type of the elements in the traversable structure.",
1231 "The applicative context."
1232 )]
1233 #[document_parameters("The tuple containing the applicative value.")]
1235 #[document_returns("The tuple wrapped in the applicative context.")]
1237 #[document_examples]
1239 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1252 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>)>)
1253 ) -> 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>)>)
1254 where
1255 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1256 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1257 let (first, second) = ta;
1258 F::map(move |a| (a, second.clone()), first)
1259 }
1260 }
1261
1262 #[document_type_parameters("The type of the second value in the tuple.")]
1263 impl<Second: 'static> ParFoldable for Tuple2SecondAppliedBrand<Second> {
1264 #[document_signature]
1268 #[document_type_parameters(
1270 "The lifetime of the values.",
1271 "The brand of the cloneable function wrapper.",
1272 "The element type.",
1273 "The monoid type."
1274 )]
1275 #[document_parameters(
1277 "The thread-safe function to map each element to a monoid.",
1278 "The tuple to fold."
1279 )]
1280 #[document_returns("The combined monoid value.")]
1282 #[document_examples]
1283 fn par_fold_map<'a, FnBrand, A, M>(
1298 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1299 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1300 ) -> M
1301 where
1302 FnBrand: 'a + SendCloneableFn,
1303 A: 'a + Clone + Send + Sync,
1304 M: Monoid + Send + Sync + 'a, {
1305 func(fa.0)
1306 }
1307
1308 #[document_signature]
1312 #[document_type_parameters(
1314 "The lifetime of the values.",
1315 "The brand of the cloneable function wrapper.",
1316 "The element type.",
1317 "The accumulator type."
1318 )]
1319 #[document_parameters(
1321 "The thread-safe function to apply to each element and the accumulator.",
1322 "The initial value.",
1323 "The tuple to fold."
1324 )]
1325 #[document_returns("The final accumulator value.")]
1327 #[document_examples]
1328 fn par_fold_right<'a, FnBrand, A, B>(
1340 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1341 initial: B,
1342 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1343 ) -> B
1344 where
1345 FnBrand: 'a + SendCloneableFn,
1346 A: 'a + Clone + Send + Sync,
1347 B: Send + Sync + 'a, {
1348 func((fa.0, initial))
1349 }
1350 }
1351}
1352
1353#[cfg(test)]
1354mod tests {
1355
1356 use {
1357 crate::{
1358 brands::*,
1359 classes::{
1360 CloneableFn,
1361 bifunctor::*,
1362 },
1363 functions::*,
1364 },
1365 quickcheck_macros::quickcheck,
1366 };
1367
1368 #[test]
1372 fn test_bimap() {
1373 let x = (1, 5);
1374 assert_eq!(bimap::<Tuple2Brand, _, _, _, _>(|a| a + 1, |b| b * 2, x), (2, 10));
1375 }
1376
1377 #[quickcheck]
1381 fn bifunctor_identity(
1382 first: String,
1383 second: i32,
1384 ) -> bool {
1385 let x = (first, second);
1386 bimap::<Tuple2Brand, _, _, _, _>(identity, identity, x.clone()) == x
1387 }
1388
1389 #[quickcheck]
1391 fn bifunctor_composition(
1392 first: i32,
1393 second: i32,
1394 ) -> bool {
1395 let x = (first, second);
1396 let f = |x: i32| x.wrapping_add(1);
1397 let g = |x: i32| x.wrapping_mul(2);
1398 let h = |x: i32| x.wrapping_sub(1);
1399 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1400
1401 bimap::<Tuple2Brand, _, _, _, _>(compose(f, g), compose(h, i), x)
1402 == bimap::<Tuple2Brand, _, _, _, _>(f, h, bimap::<Tuple2Brand, _, _, _, _>(g, i, x))
1403 }
1404
1405 #[quickcheck]
1409 fn functor_identity(
1410 first: String,
1411 second: i32,
1412 ) -> bool {
1413 let x = (first, second);
1414 map::<Tuple2FirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1415 }
1416
1417 #[quickcheck]
1419 fn functor_composition(
1420 first: String,
1421 second: i32,
1422 ) -> bool {
1423 let x = (first, second);
1424 let f = |x: i32| x.wrapping_add(1);
1425 let g = |x: i32| x.wrapping_mul(2);
1426 map::<Tuple2FirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1427 == map::<Tuple2FirstAppliedBrand<String>, _, _>(
1428 f,
1429 map::<Tuple2FirstAppliedBrand<String>, _, _>(g, x),
1430 )
1431 }
1432
1433 #[quickcheck]
1437 fn applicative_identity(
1438 first: String,
1439 second: i32,
1440 ) -> bool {
1441 let v = (first, second);
1442 apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1443 pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1444 v.clone(),
1445 ) == v
1446 }
1447
1448 #[quickcheck]
1450 fn applicative_homomorphism(x: i32) -> bool {
1451 let f = |x: i32| x.wrapping_mul(2);
1452 apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1453 pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1454 pure::<Tuple2FirstAppliedBrand<String>, _>(x),
1455 ) == pure::<Tuple2FirstAppliedBrand<String>, _>(f(x))
1456 }
1457
1458 #[quickcheck]
1460 fn applicative_composition(
1461 w_first: String,
1462 w_second: i32,
1463 u_seed: i32,
1464 v_seed: i32,
1465 ) -> bool {
1466 let w = (w_first, w_second);
1467
1468 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1469 let u = pure::<Tuple2FirstAppliedBrand<String>, _>(u_fn);
1470
1471 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1472 let v = pure::<Tuple2FirstAppliedBrand<String>, _>(v_fn);
1473
1474 let vw = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1476 let rhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u.clone(), vw);
1477
1478 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1480 let f = f.clone();
1481 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1482 let f = f.clone();
1483 let g = g.clone();
1484 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1485 })
1486 });
1487
1488 let pure_compose = pure::<Tuple2FirstAppliedBrand<String>, _>(compose_fn);
1489 let u_applied = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(pure_compose, u);
1490 let uv = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u_applied, v);
1491 let lhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(uv, w);
1492
1493 lhs == rhs
1494 }
1495
1496 #[quickcheck]
1498 fn applicative_interchange(
1499 y: i32,
1500 u_seed: i32,
1501 ) -> bool {
1502 let f = move |x: i32| x.wrapping_mul(u_seed);
1504 let u = pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1505
1506 let lhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1507 u.clone(),
1508 pure::<Tuple2FirstAppliedBrand<String>, _>(y),
1509 );
1510
1511 let rhs_fn =
1512 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1513 let rhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1514 pure::<Tuple2FirstAppliedBrand<String>, _>(rhs_fn),
1515 u,
1516 );
1517
1518 lhs == rhs
1519 }
1520
1521 #[quickcheck]
1525 fn monad_left_identity(a: i32) -> bool {
1526 let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
1527 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1528 pure::<Tuple2FirstAppliedBrand<String>, _>(a),
1529 f,
1530 ) == f(a)
1531 }
1532
1533 #[quickcheck]
1535 fn monad_right_identity(
1536 first: String,
1537 second: i32,
1538 ) -> bool {
1539 let m = (first, second);
1540 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1541 m.clone(),
1542 pure::<Tuple2FirstAppliedBrand<String>, _>,
1543 ) == m
1544 }
1545
1546 #[quickcheck]
1548 fn monad_associativity(
1549 first: String,
1550 second: i32,
1551 ) -> bool {
1552 let m = (first, second);
1553 let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
1554 let g = |x: i32| ("g".to_string(), x.wrapping_add(1));
1555 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1556 bind::<Tuple2FirstAppliedBrand<String>, _, _>(m.clone(), f),
1557 g,
1558 ) == bind::<Tuple2FirstAppliedBrand<String>, _, _>(m, |x| {
1559 bind::<Tuple2FirstAppliedBrand<String>, _, _>(f(x), g)
1560 })
1561 }
1562
1563 #[test]
1567 fn par_fold_map_tuple2_with_first() {
1568 let x = ("a".to_string(), 1);
1569 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1570 assert_eq!(
1571 par_fold_map::<ArcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(f, x),
1572 "1".to_string()
1573 );
1574 }
1575
1576 #[test]
1578 fn par_fold_right_tuple2_with_first() {
1579 let x = ("a".to_string(), 1);
1580 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1581 assert_eq!(
1582 par_fold_right::<ArcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(f, 10, x),
1583 11
1584 );
1585 }
1586
1587 #[test]
1591 fn par_fold_map_tuple2_with_second() {
1592 let x = (1, "a".to_string());
1593 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1594 assert_eq!(
1595 par_fold_map::<ArcFnBrand, Tuple2SecondAppliedBrand<String>, _, _>(f, x),
1596 "1".to_string()
1597 );
1598 }
1599
1600 #[test]
1602 fn par_fold_right_tuple2_with_second() {
1603 let x = (1, "a".to_string());
1604 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1605 assert_eq!(
1606 par_fold_right::<ArcFnBrand, Tuple2SecondAppliedBrand<String>, _, _>(f, 10, x),
1607 11
1608 );
1609 }
1610}