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 Pointed,
28 Semiapplicative,
29 Semigroup,
30 Semimonad,
31 Traversable,
32 },
33 impl_kind,
34 kinds::*,
35 },
36 fp_macros::*,
37 };
38
39 impl_kind! {
40 for Tuple2Brand {
41 type Of<First, Second> = (First, Second);
42 }
43 }
44
45 impl_kind! {
46 for Tuple2Brand {
47 type Of<'a, First: 'a, Second: 'a>: 'a = (First, Second);
48 }
49 }
50
51 impl Bifunctor for Tuple2Brand {
52 #[document_signature]
56 #[document_type_parameters(
58 "The lifetime of the values.",
59 "The type of the first value.",
60 "The type of the mapped first value.",
61 "The type of the second value.",
62 "The type of the mapped second value."
63 )]
64 #[document_parameters(
66 "The function to apply to the first value.",
67 "The function to apply to the second value.",
68 "The tuple to map over."
69 )]
70 #[document_returns("A new tuple containing the mapped values.")]
72 #[document_examples]
73 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
85 f: impl Fn(A) -> B + 'a,
86 g: impl Fn(C) -> D + 'a,
87 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
88 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
89 (f(p.0), g(p.1))
90 }
91 }
92
93 impl Bifoldable for Tuple2Brand {
94 #[document_signature]
99 #[document_type_parameters(
101 "The lifetime of the values.",
102 "The brand of the cloneable function to use.",
103 "The type of the first element.",
104 "The type of the second element.",
105 "The accumulator type."
106 )]
107 #[document_parameters(
109 "The step function applied to the first element.",
110 "The step function applied to the second element.",
111 "The initial accumulator.",
112 "The tuple to fold."
113 )]
114 #[document_returns("`f(a, g(b, z))`.")]
116 #[document_examples]
117 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
135 f: impl Fn(A, C) -> C + 'a,
136 g: impl Fn(B, C) -> C + 'a,
137 z: C,
138 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
139 ) -> C {
140 let (a, b) = p;
141 f(a, g(b, z))
142 }
143
144 #[document_signature]
149 #[document_type_parameters(
151 "The lifetime of the values.",
152 "The brand of the cloneable function to use.",
153 "The type of the first element.",
154 "The type of the second element.",
155 "The accumulator type."
156 )]
157 #[document_parameters(
159 "The step function applied to the first element.",
160 "The step function applied to the second element.",
161 "The initial accumulator.",
162 "The tuple to fold."
163 )]
164 #[document_returns("`g(f(z, a), b)`.")]
166 #[document_examples]
167 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
185 f: impl Fn(C, A) -> C + 'a,
186 g: impl Fn(C, B) -> C + 'a,
187 z: C,
188 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
189 ) -> C {
190 let (a, b) = p;
191 g(f(z, a), b)
192 }
193
194 #[document_signature]
198 #[document_type_parameters(
200 "The lifetime of the values.",
201 "The brand of the cloneable function to use.",
202 "The type of the first element.",
203 "The type of the second element.",
204 "The monoid type."
205 )]
206 #[document_parameters(
208 "The function mapping the first element to the monoid.",
209 "The function mapping the second element to the monoid.",
210 "The tuple to fold."
211 )]
212 #[document_returns("`M::append(f(a), g(b))`.")]
214 #[document_examples]
215 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
232 f: impl Fn(A) -> M + 'a,
233 g: impl Fn(B) -> M + 'a,
234 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
235 ) -> M
236 where
237 M: Monoid + 'a, {
238 let (a, b) = p;
239 M::append(f(a), g(b))
240 }
241 }
242
243 impl Bitraversable for Tuple2Brand {
244 #[document_signature]
249 #[document_type_parameters(
251 "The lifetime of the values.",
252 "The type of the first element.",
253 "The type of the second element.",
254 "The output type for the first element.",
255 "The output type for the second element.",
256 "The applicative context."
257 )]
258 #[document_parameters(
260 "The function applied to the first element.",
261 "The function applied to the second element.",
262 "The tuple to traverse."
263 )]
264 #[document_returns("`lift2(|c, d| (c, d), f(a), g(b))`.")]
266 #[document_examples]
267 fn bi_traverse<
284 'a,
285 A: 'a + Clone,
286 B: 'a + Clone,
287 C: 'a + Clone,
288 D: 'a + Clone,
289 F: Applicative,
290 >(
291 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
292 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
293 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
294 ) -> 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>)>)
295 {
296 let (a, b) = p;
297 F::lift2(|c, d| (c, d), f(a), g(b))
298 }
299 }
300
301 impl_kind! {
304 impl<First: 'static> for Tuple2FirstAppliedBrand<First> {
305 type Of<'a, A: 'a>: 'a = (First, A);
306 }
307 }
308
309 #[document_type_parameters("The type of the first value in the tuple.")]
310 impl<First: 'static> Functor for Tuple2FirstAppliedBrand<First> {
311 #[document_signature]
315 #[document_type_parameters(
317 "The lifetime of the values.",
318 "The type of the second value.",
319 "The type of the result of applying the function."
320 )]
321 #[document_parameters(
323 "The function to apply to the second value.",
324 "The tuple to map over."
325 )]
326 #[document_returns(
328 "A new tuple containing the result of applying the function to the second value."
329 )]
330 #[document_examples]
331 fn map<'a, A: 'a, B: 'a>(
341 func: impl Fn(A) -> B + 'a,
342 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
343 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
344 (fa.0, func(fa.1))
345 }
346 }
347
348 #[document_type_parameters("The type of the first value in the tuple.")]
349 impl<First: Clone + 'static> Lift for Tuple2FirstAppliedBrand<First>
350 where
351 First: Semigroup,
352 {
353 #[document_signature]
357 #[document_type_parameters(
359 "The lifetime of the values.",
360 "The type of the first second value.",
361 "The type of the second second value.",
362 "The type of the result second value."
363 )]
364 #[document_parameters(
366 "The binary function to apply to the second values.",
367 "The first tuple.",
368 "The second tuple."
369 )]
370 #[document_returns(
372 "A new tuple where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
373 )]
374 #[document_examples]
375 fn lift2<'a, A, B, C>(
392 func: impl Fn(A, B) -> C + 'a,
393 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
394 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
395 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
396 where
397 A: Clone + 'a,
398 B: Clone + 'a,
399 C: 'a, {
400 (Semigroup::append(fa.0, fb.0), func(fa.1, fb.1))
401 }
402 }
403
404 #[document_type_parameters("The type of the first value in the tuple.")]
405 impl<First: Clone + 'static> Pointed for Tuple2FirstAppliedBrand<First>
406 where
407 First: Monoid,
408 {
409 #[document_signature]
413 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
415 #[document_parameters("The value to wrap.")]
417 #[document_returns("A tuple containing the empty value of the first type and `a`.")]
419 #[document_examples]
421 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
431 (Monoid::empty(), a)
432 }
433 }
434
435 #[document_type_parameters("The type of the first value in the tuple.")]
436 impl<First: Clone + Semigroup + 'static> ApplyFirst for Tuple2FirstAppliedBrand<First> {}
437 #[document_type_parameters("The type of the first value in the tuple.")]
438 impl<First: Clone + Semigroup + 'static> ApplySecond for Tuple2FirstAppliedBrand<First> {}
439
440 #[document_type_parameters("The type of the first value in the tuple.")]
441 impl<First: Clone + 'static> Semiapplicative for Tuple2FirstAppliedBrand<First>
442 where
443 First: Semigroup,
444 {
445 #[document_signature]
449 #[document_type_parameters(
451 "The lifetime of the values.",
452 "The brand of the cloneable function wrapper.",
453 "The type of the input value.",
454 "The type of the output value."
455 )]
456 #[document_parameters(
458 "The tuple containing the function.",
459 "The tuple containing the value."
460 )]
461 #[document_returns(
463 "A new tuple where the first values are combined and the function is applied to the second value."
464 )]
465 #[document_examples]
466 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
480 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
481 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
482 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
483 (Semigroup::append(ff.0, fa.0), ff.1(fa.1))
484 }
485 }
486
487 #[document_type_parameters("The type of the first value in the tuple.")]
488 impl<First: Clone + 'static> Semimonad for Tuple2FirstAppliedBrand<First>
489 where
490 First: Semigroup,
491 {
492 #[document_signature]
496 #[document_type_parameters(
498 "The lifetime of the values.",
499 "The type of the result of the first computation.",
500 "The type of the result of the second computation."
501 )]
502 #[document_parameters("The first tuple.", "The function to apply to the second value.")]
504 #[document_returns("A new tuple where the first values are combined.")]
506 #[document_examples]
508 fn bind<'a, A: 'a, B: 'a>(
524 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
525 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
526 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
527 let (first, second) = ma;
528 let (next_first, next_second) = func(second);
529 (Semigroup::append(first, next_first), next_second)
530 }
531 }
532
533 #[document_type_parameters("The type of the first value in the tuple.")]
534 impl<First: 'static> Foldable for Tuple2FirstAppliedBrand<First> {
535 #[document_signature]
539 #[document_type_parameters(
541 "The lifetime of the values.",
542 "The brand of the cloneable function to use.",
543 "The type of the elements in the structure.",
544 "The type of the accumulator."
545 )]
546 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
548 #[document_returns("`func(a, initial)`.")]
550 #[document_examples]
552 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
565 func: impl Fn(A, B) -> B + 'a,
566 initial: B,
567 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
568 ) -> B
569 where
570 FnBrand: CloneableFn + 'a, {
571 func(fa.1, initial)
572 }
573
574 #[document_signature]
578 #[document_type_parameters(
580 "The lifetime of the values.",
581 "The brand of the cloneable function to use.",
582 "The type of the elements in the structure.",
583 "The type of the accumulator."
584 )]
585 #[document_parameters(
587 "The function to apply to the accumulator and each element.",
588 "The initial value of the accumulator.",
589 "The tuple to fold."
590 )]
591 #[document_returns("`func(initial, a)`.")]
593 #[document_examples]
594 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
607 func: impl Fn(B, A) -> B + 'a,
608 initial: B,
609 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
610 ) -> B
611 where
612 FnBrand: CloneableFn + 'a, {
613 func(initial, fa.1)
614 }
615
616 #[document_signature]
620 #[document_type_parameters(
622 "The lifetime of the values.",
623 "The brand of the cloneable function to use.",
624 "The type of the elements in the structure.",
625 "The type of the monoid."
626 )]
627 #[document_parameters("The mapping function.", "The tuple to fold.")]
629 #[document_returns("`func(a)`.")]
631 #[document_examples]
633 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
646 func: impl Fn(A) -> M + 'a,
647 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
648 ) -> M
649 where
650 M: Monoid + 'a,
651 FnBrand: CloneableFn + 'a, {
652 func(fa.1)
653 }
654 }
655
656 #[document_type_parameters("The type of the first value in the tuple.")]
657 impl<First: Clone + 'static> Traversable for Tuple2FirstAppliedBrand<First> {
658 #[document_signature]
662 #[document_type_parameters(
664 "The lifetime of the values.",
665 "The type of the elements in the traversable structure.",
666 "The type of the elements in the resulting traversable structure.",
667 "The applicative context."
668 )]
669 #[document_parameters(
671 "The function to apply to each element, returning a value in an applicative context.",
672 "The tuple to traverse."
673 )]
674 #[document_returns("The tuple wrapped in the applicative context.")]
676 #[document_examples]
677 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
690 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
691 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
692 ) -> 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>)>)
693 where
694 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
695 let (first, second) = ta;
696 F::map(move |b| (first.clone(), b), func(second))
697 }
698
699 #[document_signature]
703 #[document_type_parameters(
705 "The lifetime of the values.",
706 "The type of the elements in the traversable structure.",
707 "The applicative context."
708 )]
709 #[document_parameters("The tuple containing the applicative value.")]
711 #[document_returns("The tuple wrapped in the applicative context.")]
713 #[document_examples]
715 fn sequence<'a, A: 'a + Clone, F: Applicative>(
728 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>)>)
729 ) -> 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>)>)
730 where
731 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
732 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
733 let (first, second) = ta;
734 F::map(move |a| (first.clone(), a), second)
735 }
736 }
737
738 impl_kind! {
741 impl<Second: 'static> for Tuple2SecondAppliedBrand<Second> {
742 type Of<'a, A: 'a>: 'a = (A, Second);
743 }
744 }
745
746 #[document_type_parameters("The type of the second value in the tuple.")]
747 impl<Second: 'static> Functor for Tuple2SecondAppliedBrand<Second> {
748 #[document_signature]
752 #[document_type_parameters(
754 "The lifetime of the values.",
755 "The type of the first value.",
756 "The type of the result of applying the function."
757 )]
758 #[document_parameters(
760 "The function to apply to the first value.",
761 "The tuple to map over."
762 )]
763 #[document_returns(
765 "A new tuple containing the result of applying the function to the first value."
766 )]
767 #[document_examples]
768 fn map<'a, A: 'a, B: 'a>(
778 func: impl Fn(A) -> B + 'a,
779 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
780 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
781 (func(fa.0), fa.1)
782 }
783 }
784
785 #[document_type_parameters("The type of the second value in the tuple.")]
786 impl<Second: Clone + 'static> Lift for Tuple2SecondAppliedBrand<Second>
787 where
788 Second: Semigroup,
789 {
790 #[document_signature]
794 #[document_type_parameters(
796 "The lifetime of the values.",
797 "The type of the first first value.",
798 "The type of the second first value.",
799 "The type of the result first value."
800 )]
801 #[document_parameters(
803 "The binary function to apply to the first values.",
804 "The first tuple.",
805 "The second tuple."
806 )]
807 #[document_returns(
809 "A new tuple where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
810 )]
811 #[document_examples]
812 fn lift2<'a, A, B, C>(
829 func: impl Fn(A, B) -> C + 'a,
830 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
831 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
832 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
833 where
834 A: Clone + 'a,
835 B: Clone + 'a,
836 C: 'a, {
837 (func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
838 }
839 }
840
841 #[document_type_parameters("The type of the second value in the tuple.")]
842 impl<Second: Clone + 'static> Pointed for Tuple2SecondAppliedBrand<Second>
843 where
844 Second: Monoid,
845 {
846 #[document_signature]
850 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
852 #[document_parameters("The value to wrap.")]
854 #[document_returns("A tuple containing `a` and the empty value of the second type.")]
856 #[document_examples]
858 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
868 (a, Monoid::empty())
869 }
870 }
871
872 #[document_type_parameters("The type of the second value in the tuple.")]
873 impl<Second: Clone + Semigroup + 'static> ApplyFirst for Tuple2SecondAppliedBrand<Second> {}
874 #[document_type_parameters("The type of the second value in the tuple.")]
875 impl<Second: Clone + Semigroup + 'static> ApplySecond for Tuple2SecondAppliedBrand<Second> {}
876
877 #[document_type_parameters("The type of the second value in the tuple.")]
878 impl<Second: Clone + 'static> Semiapplicative for Tuple2SecondAppliedBrand<Second>
879 where
880 Second: Semigroup,
881 {
882 #[document_signature]
886 #[document_type_parameters(
888 "The lifetime of the values.",
889 "The brand of the cloneable function wrapper.",
890 "The type of the input value.",
891 "The type of the output value."
892 )]
893 #[document_parameters(
895 "The tuple containing the function.",
896 "The tuple containing the value."
897 )]
898 #[document_returns(
900 "A new tuple where the function is applied to the first value and the second values are combined."
901 )]
902 #[document_examples]
903 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
917 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
918 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
919 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
920 (ff.0(fa.0), Semigroup::append(ff.1, fa.1))
921 }
922 }
923
924 #[document_type_parameters("The type of the second value in the tuple.")]
925 impl<Second: Clone + 'static> Semimonad for Tuple2SecondAppliedBrand<Second>
926 where
927 Second: Semigroup,
928 {
929 #[document_signature]
933 #[document_type_parameters(
935 "The lifetime of the values.",
936 "The type of the result of the first computation.",
937 "The type of the result of the second computation."
938 )]
939 #[document_parameters("The first tuple.", "The function to apply to the first value.")]
941 #[document_returns("A new tuple where the second values are combined.")]
943 #[document_examples]
945 fn bind<'a, A: 'a, B: 'a>(
961 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
962 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
963 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
964 let (first, second) = ma;
965 let (next_first, next_second) = func(first);
966 (next_first, Semigroup::append(second, next_second))
967 }
968 }
969
970 #[document_type_parameters("The type of the second value in the tuple.")]
971 impl<Second: 'static> Foldable for Tuple2SecondAppliedBrand<Second> {
972 #[document_signature]
976 #[document_type_parameters(
978 "The lifetime of the values.",
979 "The brand of the cloneable function to use.",
980 "The type of the elements in the structure.",
981 "The type of the accumulator."
982 )]
983 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
985 #[document_returns("`func(a, initial)`.")]
987 #[document_examples]
989 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1002 func: impl Fn(A, B) -> B + 'a,
1003 initial: B,
1004 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1005 ) -> B
1006 where
1007 FnBrand: CloneableFn + 'a, {
1008 func(fa.0, initial)
1009 }
1010
1011 #[document_signature]
1015 #[document_type_parameters(
1017 "The lifetime of the values.",
1018 "The brand of the cloneable function to use.",
1019 "The type of the elements in the structure.",
1020 "The type of the accumulator."
1021 )]
1022 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1024 #[document_returns("`func(initial, a)`.")]
1026 #[document_examples]
1028 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1041 func: impl Fn(B, A) -> B + 'a,
1042 initial: B,
1043 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1044 ) -> B
1045 where
1046 FnBrand: CloneableFn + 'a, {
1047 func(initial, fa.0)
1048 }
1049
1050 #[document_signature]
1054 #[document_type_parameters(
1056 "The lifetime of the values.",
1057 "The brand of the cloneable function to use.",
1058 "The type of the elements in the structure.",
1059 "The type of the monoid."
1060 )]
1061 #[document_parameters("The mapping function.", "The tuple to fold.")]
1063 #[document_returns("`func(a)`.")]
1065 #[document_examples]
1067 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1080 func: impl Fn(A) -> M + 'a,
1081 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1082 ) -> M
1083 where
1084 M: Monoid + 'a,
1085 FnBrand: CloneableFn + 'a, {
1086 func(fa.0)
1087 }
1088 }
1089
1090 #[document_type_parameters("The type of the second value in the tuple.")]
1091 impl<Second: Clone + 'static> Traversable for Tuple2SecondAppliedBrand<Second> {
1092 #[document_signature]
1096 #[document_type_parameters(
1098 "The lifetime of the values.",
1099 "The type of the elements in the traversable structure.",
1100 "The type of the elements in the resulting traversable structure.",
1101 "The applicative context."
1102 )]
1103 #[document_parameters("The function to apply.", "The tuple to traverse.")]
1105 #[document_returns("The tuple wrapped in the applicative context.")]
1107 #[document_examples]
1109 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1122 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1123 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1124 ) -> 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>)>)
1125 where
1126 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1127 let (first, second) = ta;
1128 F::map(move |b| (b, second.clone()), func(first))
1129 }
1130
1131 #[document_signature]
1135 #[document_type_parameters(
1137 "The lifetime of the values.",
1138 "The type of the elements in the traversable structure.",
1139 "The applicative context."
1140 )]
1141 #[document_parameters("The tuple containing the applicative value.")]
1143 #[document_returns("The tuple wrapped in the applicative context.")]
1145 #[document_examples]
1147 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1160 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>)>)
1161 ) -> 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>)>)
1162 where
1163 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1164 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1165 let (first, second) = ta;
1166 F::map(move |a| (a, second.clone()), first)
1167 }
1168 }
1169}
1170
1171#[cfg(test)]
1172mod tests {
1173
1174 use {
1175 crate::{
1176 brands::*,
1177 classes::{
1178 CloneableFn,
1179 bifunctor::*,
1180 },
1181 functions::*,
1182 },
1183 quickcheck_macros::quickcheck,
1184 };
1185
1186 #[test]
1190 fn test_bimap() {
1191 let x = (1, 5);
1192 assert_eq!(bimap::<Tuple2Brand, _, _, _, _>(|a| a + 1, |b| b * 2, x), (2, 10));
1193 }
1194
1195 #[quickcheck]
1199 fn bifunctor_identity(
1200 first: String,
1201 second: i32,
1202 ) -> bool {
1203 let x = (first, second);
1204 bimap::<Tuple2Brand, _, _, _, _>(identity, identity, x.clone()) == x
1205 }
1206
1207 #[quickcheck]
1209 fn bifunctor_composition(
1210 first: i32,
1211 second: i32,
1212 ) -> bool {
1213 let x = (first, second);
1214 let f = |x: i32| x.wrapping_add(1);
1215 let g = |x: i32| x.wrapping_mul(2);
1216 let h = |x: i32| x.wrapping_sub(1);
1217 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1218
1219 bimap::<Tuple2Brand, _, _, _, _>(compose(f, g), compose(h, i), x)
1220 == bimap::<Tuple2Brand, _, _, _, _>(f, h, bimap::<Tuple2Brand, _, _, _, _>(g, i, x))
1221 }
1222
1223 #[quickcheck]
1227 fn functor_identity(
1228 first: String,
1229 second: i32,
1230 ) -> bool {
1231 let x = (first, second);
1232 map::<Tuple2FirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1233 }
1234
1235 #[quickcheck]
1237 fn functor_composition(
1238 first: String,
1239 second: i32,
1240 ) -> bool {
1241 let x = (first, second);
1242 let f = |x: i32| x.wrapping_add(1);
1243 let g = |x: i32| x.wrapping_mul(2);
1244 map::<Tuple2FirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1245 == map::<Tuple2FirstAppliedBrand<String>, _, _>(
1246 f,
1247 map::<Tuple2FirstAppliedBrand<String>, _, _>(g, x),
1248 )
1249 }
1250
1251 #[quickcheck]
1255 fn applicative_identity(
1256 first: String,
1257 second: i32,
1258 ) -> bool {
1259 let v = (first, second);
1260 apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1261 pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1262 v.clone(),
1263 ) == v
1264 }
1265
1266 #[quickcheck]
1268 fn applicative_homomorphism(x: i32) -> bool {
1269 let f = |x: i32| x.wrapping_mul(2);
1270 apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1271 pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1272 pure::<Tuple2FirstAppliedBrand<String>, _>(x),
1273 ) == pure::<Tuple2FirstAppliedBrand<String>, _>(f(x))
1274 }
1275
1276 #[quickcheck]
1278 fn applicative_composition(
1279 w_first: String,
1280 w_second: i32,
1281 u_seed: i32,
1282 v_seed: i32,
1283 ) -> bool {
1284 let w = (w_first, w_second);
1285
1286 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1287 let u = pure::<Tuple2FirstAppliedBrand<String>, _>(u_fn);
1288
1289 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1290 let v = pure::<Tuple2FirstAppliedBrand<String>, _>(v_fn);
1291
1292 let vw = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1294 let rhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u.clone(), vw);
1295
1296 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1298 let f = f.clone();
1299 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1300 let f = f.clone();
1301 let g = g.clone();
1302 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1303 })
1304 });
1305
1306 let pure_compose = pure::<Tuple2FirstAppliedBrand<String>, _>(compose_fn);
1307 let u_applied = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(pure_compose, u);
1308 let uv = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u_applied, v);
1309 let lhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(uv, w);
1310
1311 lhs == rhs
1312 }
1313
1314 #[quickcheck]
1316 fn applicative_interchange(
1317 y: i32,
1318 u_seed: i32,
1319 ) -> bool {
1320 let f = move |x: i32| x.wrapping_mul(u_seed);
1322 let u = pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1323
1324 let lhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1325 u.clone(),
1326 pure::<Tuple2FirstAppliedBrand<String>, _>(y),
1327 );
1328
1329 let rhs_fn =
1330 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1331 let rhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1332 pure::<Tuple2FirstAppliedBrand<String>, _>(rhs_fn),
1333 u,
1334 );
1335
1336 lhs == rhs
1337 }
1338
1339 #[quickcheck]
1343 fn monad_left_identity(a: i32) -> bool {
1344 let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
1345 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1346 pure::<Tuple2FirstAppliedBrand<String>, _>(a),
1347 f,
1348 ) == f(a)
1349 }
1350
1351 #[quickcheck]
1353 fn monad_right_identity(
1354 first: String,
1355 second: i32,
1356 ) -> bool {
1357 let m = (first, second);
1358 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1359 m.clone(),
1360 pure::<Tuple2FirstAppliedBrand<String>, _>,
1361 ) == m
1362 }
1363
1364 #[quickcheck]
1366 fn monad_associativity(
1367 first: String,
1368 second: i32,
1369 ) -> bool {
1370 let m = (first, second);
1371 let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
1372 let g = |x: i32| ("g".to_string(), x.wrapping_add(1));
1373 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1374 bind::<Tuple2FirstAppliedBrand<String>, _, _>(m.clone(), f),
1375 g,
1376 ) == bind::<Tuple2FirstAppliedBrand<String>, _, _>(m, |x| {
1377 bind::<Tuple2FirstAppliedBrand<String>, _, _>(f(x), g)
1378 })
1379 }
1380}