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 MonadRec,
27 Monoid,
28 Pointed,
29 Semiapplicative,
30 Semigroup,
31 Semimonad,
32 Traversable,
33 },
34 impl_kind,
35 kinds::*,
36 },
37 core::ops::ControlFlow,
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: Clone + 'static> MonadRec for Tuple2FirstAppliedBrand<First>
537 where
538 First: Monoid,
539 {
540 #[document_signature]
546 #[document_type_parameters(
548 "The lifetime of the computation.",
549 "The type of the initial value and loop state.",
550 "The type of the result."
551 )]
552 #[document_parameters("The step function.", "The initial value.")]
554 #[document_returns(
556 "A tuple with the accumulated first value and the result of the computation."
557 )]
558 #[document_examples]
560 fn tail_rec_m<'a, A: 'a, B: 'a>(
584 func: impl Fn(
585 A,
586 )
587 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
588 + 'a,
589 initial: A,
590 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
591 let mut acc: First = Monoid::empty();
592 let mut current = initial;
593 loop {
594 let (first, step) = func(current);
595 acc = Semigroup::append(acc, first);
596 match step {
597 ControlFlow::Continue(next) => current = next,
598 ControlFlow::Break(b) => return (acc, b),
599 }
600 }
601 }
602 }
603
604 #[document_type_parameters("The type of the first value in the tuple.")]
605 impl<First: 'static> Foldable for Tuple2FirstAppliedBrand<First> {
606 #[document_signature]
610 #[document_type_parameters(
612 "The lifetime of the values.",
613 "The brand of the cloneable function to use.",
614 "The type of the elements in the structure.",
615 "The type of the accumulator."
616 )]
617 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
619 #[document_returns("`func(a, initial)`.")]
621 #[document_examples]
623 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
636 func: impl Fn(A, B) -> B + 'a,
637 initial: B,
638 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
639 ) -> B
640 where
641 FnBrand: CloneableFn + 'a, {
642 func(fa.1, initial)
643 }
644
645 #[document_signature]
649 #[document_type_parameters(
651 "The lifetime of the values.",
652 "The brand of the cloneable function to use.",
653 "The type of the elements in the structure.",
654 "The type of the accumulator."
655 )]
656 #[document_parameters(
658 "The function to apply to the accumulator and each element.",
659 "The initial value of the accumulator.",
660 "The tuple to fold."
661 )]
662 #[document_returns("`func(initial, a)`.")]
664 #[document_examples]
665 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
678 func: impl Fn(B, A) -> B + 'a,
679 initial: B,
680 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
681 ) -> B
682 where
683 FnBrand: CloneableFn + 'a, {
684 func(initial, fa.1)
685 }
686
687 #[document_signature]
691 #[document_type_parameters(
693 "The lifetime of the values.",
694 "The brand of the cloneable function to use.",
695 "The type of the elements in the structure.",
696 "The type of the monoid."
697 )]
698 #[document_parameters("The mapping function.", "The tuple to fold.")]
700 #[document_returns("`func(a)`.")]
702 #[document_examples]
704 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
717 func: impl Fn(A) -> M + 'a,
718 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
719 ) -> M
720 where
721 M: Monoid + 'a,
722 FnBrand: CloneableFn + 'a, {
723 func(fa.1)
724 }
725 }
726
727 #[document_type_parameters("The type of the first value in the tuple.")]
728 impl<First: Clone + 'static> Traversable for Tuple2FirstAppliedBrand<First> {
729 #[document_signature]
733 #[document_type_parameters(
735 "The lifetime of the values.",
736 "The type of the elements in the traversable structure.",
737 "The type of the elements in the resulting traversable structure.",
738 "The applicative context."
739 )]
740 #[document_parameters(
742 "The function to apply to each element, returning a value in an applicative context.",
743 "The tuple to traverse."
744 )]
745 #[document_returns("The tuple wrapped in the applicative context.")]
747 #[document_examples]
748 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
761 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
762 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
763 ) -> 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>)>)
764 where
765 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
766 let (first, second) = ta;
767 F::map(move |b| (first.clone(), b), func(second))
768 }
769
770 #[document_signature]
774 #[document_type_parameters(
776 "The lifetime of the values.",
777 "The type of the elements in the traversable structure.",
778 "The applicative context."
779 )]
780 #[document_parameters("The tuple containing the applicative value.")]
782 #[document_returns("The tuple wrapped in the applicative context.")]
784 #[document_examples]
786 fn sequence<'a, A: 'a + Clone, F: Applicative>(
799 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>)>)
800 ) -> 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>)>)
801 where
802 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
803 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
804 let (first, second) = ta;
805 F::map(move |a| (first.clone(), a), second)
806 }
807 }
808
809 impl_kind! {
812 impl<Second: 'static> for Tuple2SecondAppliedBrand<Second> {
813 type Of<'a, A: 'a>: 'a = (A, Second);
814 }
815 }
816
817 #[document_type_parameters("The type of the second value in the tuple.")]
818 impl<Second: 'static> Functor for Tuple2SecondAppliedBrand<Second> {
819 #[document_signature]
823 #[document_type_parameters(
825 "The lifetime of the values.",
826 "The type of the first value.",
827 "The type of the result of applying the function."
828 )]
829 #[document_parameters(
831 "The function to apply to the first value.",
832 "The tuple to map over."
833 )]
834 #[document_returns(
836 "A new tuple containing the result of applying the function to the first value."
837 )]
838 #[document_examples]
839 fn map<'a, A: 'a, B: 'a>(
849 func: impl Fn(A) -> B + 'a,
850 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
851 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
852 (func(fa.0), fa.1)
853 }
854 }
855
856 #[document_type_parameters("The type of the second value in the tuple.")]
857 impl<Second: Clone + 'static> Lift for Tuple2SecondAppliedBrand<Second>
858 where
859 Second: Semigroup,
860 {
861 #[document_signature]
865 #[document_type_parameters(
867 "The lifetime of the values.",
868 "The type of the first first value.",
869 "The type of the second first value.",
870 "The type of the result first value."
871 )]
872 #[document_parameters(
874 "The binary function to apply to the first values.",
875 "The first tuple.",
876 "The second tuple."
877 )]
878 #[document_returns(
880 "A new tuple where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
881 )]
882 #[document_examples]
883 fn lift2<'a, A, B, C>(
900 func: impl Fn(A, B) -> C + 'a,
901 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
902 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
903 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
904 where
905 A: Clone + 'a,
906 B: Clone + 'a,
907 C: 'a, {
908 (func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
909 }
910 }
911
912 #[document_type_parameters("The type of the second value in the tuple.")]
913 impl<Second: Clone + 'static> Pointed for Tuple2SecondAppliedBrand<Second>
914 where
915 Second: Monoid,
916 {
917 #[document_signature]
921 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
923 #[document_parameters("The value to wrap.")]
925 #[document_returns("A tuple containing `a` and the empty value of the second type.")]
927 #[document_examples]
929 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
939 (a, Monoid::empty())
940 }
941 }
942
943 #[document_type_parameters("The type of the second value in the tuple.")]
944 impl<Second: Clone + Semigroup + 'static> ApplyFirst for Tuple2SecondAppliedBrand<Second> {}
945 #[document_type_parameters("The type of the second value in the tuple.")]
946 impl<Second: Clone + Semigroup + 'static> ApplySecond for Tuple2SecondAppliedBrand<Second> {}
947
948 #[document_type_parameters("The type of the second value in the tuple.")]
949 impl<Second: Clone + 'static> Semiapplicative for Tuple2SecondAppliedBrand<Second>
950 where
951 Second: Semigroup,
952 {
953 #[document_signature]
957 #[document_type_parameters(
959 "The lifetime of the values.",
960 "The brand of the cloneable function wrapper.",
961 "The type of the input value.",
962 "The type of the output value."
963 )]
964 #[document_parameters(
966 "The tuple containing the function.",
967 "The tuple containing the value."
968 )]
969 #[document_returns(
971 "A new tuple where the function is applied to the first value and the second values are combined."
972 )]
973 #[document_examples]
974 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
988 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
989 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
990 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
991 (ff.0(fa.0), Semigroup::append(ff.1, fa.1))
992 }
993 }
994
995 #[document_type_parameters("The type of the second value in the tuple.")]
996 impl<Second: Clone + 'static> Semimonad for Tuple2SecondAppliedBrand<Second>
997 where
998 Second: Semigroup,
999 {
1000 #[document_signature]
1004 #[document_type_parameters(
1006 "The lifetime of the values.",
1007 "The type of the result of the first computation.",
1008 "The type of the result of the second computation."
1009 )]
1010 #[document_parameters("The first tuple.", "The function to apply to the first value.")]
1012 #[document_returns("A new tuple where the second values are combined.")]
1014 #[document_examples]
1016 fn bind<'a, A: 'a, B: 'a>(
1032 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1033 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1034 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1035 let (first, second) = ma;
1036 let (next_first, next_second) = func(first);
1037 (next_first, Semigroup::append(second, next_second))
1038 }
1039 }
1040
1041 #[document_type_parameters("The type of the second value in the tuple.")]
1042 impl<Second: Clone + 'static> MonadRec for Tuple2SecondAppliedBrand<Second>
1043 where
1044 Second: Monoid,
1045 {
1046 #[document_signature]
1052 #[document_type_parameters(
1054 "The lifetime of the computation.",
1055 "The type of the initial value and loop state.",
1056 "The type of the result."
1057 )]
1058 #[document_parameters("The step function.", "The initial value.")]
1060 #[document_returns(
1062 "A tuple with the result of the computation and the accumulated second value."
1063 )]
1064 #[document_examples]
1066 fn tail_rec_m<'a, A: 'a, B: 'a>(
1090 func: impl Fn(
1091 A,
1092 )
1093 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1094 + 'a,
1095 initial: A,
1096 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1097 let mut acc: Second = Monoid::empty();
1098 let mut current = initial;
1099 loop {
1100 let (step, second) = func(current);
1101 acc = Semigroup::append(acc, second);
1102 match step {
1103 ControlFlow::Continue(next) => current = next,
1104 ControlFlow::Break(b) => return (b, acc),
1105 }
1106 }
1107 }
1108 }
1109
1110 #[document_type_parameters("The type of the second value in the tuple.")]
1111 impl<Second: 'static> Foldable for Tuple2SecondAppliedBrand<Second> {
1112 #[document_signature]
1116 #[document_type_parameters(
1118 "The lifetime of the values.",
1119 "The brand of the cloneable function to use.",
1120 "The type of the elements in the structure.",
1121 "The type of the accumulator."
1122 )]
1123 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1125 #[document_returns("`func(a, initial)`.")]
1127 #[document_examples]
1129 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1142 func: impl Fn(A, B) -> B + 'a,
1143 initial: B,
1144 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1145 ) -> B
1146 where
1147 FnBrand: CloneableFn + 'a, {
1148 func(fa.0, initial)
1149 }
1150
1151 #[document_signature]
1155 #[document_type_parameters(
1157 "The lifetime of the values.",
1158 "The brand of the cloneable function to use.",
1159 "The type of the elements in the structure.",
1160 "The type of the accumulator."
1161 )]
1162 #[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1164 #[document_returns("`func(initial, a)`.")]
1166 #[document_examples]
1168 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1181 func: impl Fn(B, A) -> B + 'a,
1182 initial: B,
1183 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1184 ) -> B
1185 where
1186 FnBrand: CloneableFn + 'a, {
1187 func(initial, fa.0)
1188 }
1189
1190 #[document_signature]
1194 #[document_type_parameters(
1196 "The lifetime of the values.",
1197 "The brand of the cloneable function to use.",
1198 "The type of the elements in the structure.",
1199 "The type of the monoid."
1200 )]
1201 #[document_parameters("The mapping function.", "The tuple to fold.")]
1203 #[document_returns("`func(a)`.")]
1205 #[document_examples]
1207 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1220 func: impl Fn(A) -> M + 'a,
1221 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1222 ) -> M
1223 where
1224 M: Monoid + 'a,
1225 FnBrand: CloneableFn + 'a, {
1226 func(fa.0)
1227 }
1228 }
1229
1230 #[document_type_parameters("The type of the second value in the tuple.")]
1231 impl<Second: Clone + 'static> Traversable for Tuple2SecondAppliedBrand<Second> {
1232 #[document_signature]
1236 #[document_type_parameters(
1238 "The lifetime of the values.",
1239 "The type of the elements in the traversable structure.",
1240 "The type of the elements in the resulting traversable structure.",
1241 "The applicative context."
1242 )]
1243 #[document_parameters("The function to apply.", "The tuple to traverse.")]
1245 #[document_returns("The tuple wrapped in the applicative context.")]
1247 #[document_examples]
1249 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1262 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1263 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1264 ) -> 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>)>)
1265 where
1266 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1267 let (first, second) = ta;
1268 F::map(move |b| (b, second.clone()), func(first))
1269 }
1270
1271 #[document_signature]
1275 #[document_type_parameters(
1277 "The lifetime of the values.",
1278 "The type of the elements in the traversable structure.",
1279 "The applicative context."
1280 )]
1281 #[document_parameters("The tuple containing the applicative value.")]
1283 #[document_returns("The tuple wrapped in the applicative context.")]
1285 #[document_examples]
1287 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1300 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>)>)
1301 ) -> 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>)>)
1302 where
1303 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1304 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1305 let (first, second) = ta;
1306 F::map(move |a| (a, second.clone()), first)
1307 }
1308 }
1309}
1310
1311#[cfg(test)]
1312mod tests {
1313
1314 use {
1315 crate::{
1316 brands::*,
1317 classes::{
1318 CloneableFn,
1319 bifunctor::*,
1320 monad_rec::tail_rec_m,
1321 },
1322 functions::*,
1323 },
1324 core::ops::ControlFlow,
1325 quickcheck_macros::quickcheck,
1326 };
1327
1328 #[test]
1332 fn test_bimap() {
1333 let x = (1, 5);
1334 assert_eq!(bimap::<Tuple2Brand, _, _, _, _>(|a| a + 1, |b| b * 2, x), (2, 10));
1335 }
1336
1337 #[quickcheck]
1341 fn bifunctor_identity(
1342 first: String,
1343 second: i32,
1344 ) -> bool {
1345 let x = (first, second);
1346 bimap::<Tuple2Brand, _, _, _, _>(identity, identity, x.clone()) == x
1347 }
1348
1349 #[quickcheck]
1351 fn bifunctor_composition(
1352 first: i32,
1353 second: i32,
1354 ) -> bool {
1355 let x = (first, second);
1356 let f = |x: i32| x.wrapping_add(1);
1357 let g = |x: i32| x.wrapping_mul(2);
1358 let h = |x: i32| x.wrapping_sub(1);
1359 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1360
1361 bimap::<Tuple2Brand, _, _, _, _>(compose(f, g), compose(h, i), x)
1362 == bimap::<Tuple2Brand, _, _, _, _>(f, h, bimap::<Tuple2Brand, _, _, _, _>(g, i, x))
1363 }
1364
1365 #[quickcheck]
1369 fn functor_identity(
1370 first: String,
1371 second: i32,
1372 ) -> bool {
1373 let x = (first, second);
1374 map::<Tuple2FirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1375 }
1376
1377 #[quickcheck]
1379 fn functor_composition(
1380 first: String,
1381 second: i32,
1382 ) -> bool {
1383 let x = (first, second);
1384 let f = |x: i32| x.wrapping_add(1);
1385 let g = |x: i32| x.wrapping_mul(2);
1386 map::<Tuple2FirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1387 == map::<Tuple2FirstAppliedBrand<String>, _, _>(
1388 f,
1389 map::<Tuple2FirstAppliedBrand<String>, _, _>(g, x),
1390 )
1391 }
1392
1393 #[quickcheck]
1397 fn applicative_identity(
1398 first: String,
1399 second: i32,
1400 ) -> bool {
1401 let v = (first, second);
1402 apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1403 pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1404 v.clone(),
1405 ) == v
1406 }
1407
1408 #[quickcheck]
1410 fn applicative_homomorphism(x: i32) -> bool {
1411 let f = |x: i32| x.wrapping_mul(2);
1412 apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1413 pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1414 pure::<Tuple2FirstAppliedBrand<String>, _>(x),
1415 ) == pure::<Tuple2FirstAppliedBrand<String>, _>(f(x))
1416 }
1417
1418 #[quickcheck]
1420 fn applicative_composition(
1421 w_first: String,
1422 w_second: i32,
1423 u_seed: i32,
1424 v_seed: i32,
1425 ) -> bool {
1426 let w = (w_first, w_second);
1427
1428 let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1429 let u = pure::<Tuple2FirstAppliedBrand<String>, _>(u_fn);
1430
1431 let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1432 let v = pure::<Tuple2FirstAppliedBrand<String>, _>(v_fn);
1433
1434 let vw = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1436 let rhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u.clone(), vw);
1437
1438 let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1440 let f = f.clone();
1441 <RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1442 let f = f.clone();
1443 let g = g.clone();
1444 <RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1445 })
1446 });
1447
1448 let pure_compose = pure::<Tuple2FirstAppliedBrand<String>, _>(compose_fn);
1449 let u_applied = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(pure_compose, u);
1450 let uv = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u_applied, v);
1451 let lhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(uv, w);
1452
1453 lhs == rhs
1454 }
1455
1456 #[quickcheck]
1458 fn applicative_interchange(
1459 y: i32,
1460 u_seed: i32,
1461 ) -> bool {
1462 let f = move |x: i32| x.wrapping_mul(u_seed);
1464 let u = pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1465
1466 let lhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1467 u.clone(),
1468 pure::<Tuple2FirstAppliedBrand<String>, _>(y),
1469 );
1470
1471 let rhs_fn =
1472 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1473 let rhs = apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1474 pure::<Tuple2FirstAppliedBrand<String>, _>(rhs_fn),
1475 u,
1476 );
1477
1478 lhs == rhs
1479 }
1480
1481 #[quickcheck]
1485 fn monad_left_identity(a: i32) -> bool {
1486 let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
1487 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1488 pure::<Tuple2FirstAppliedBrand<String>, _>(a),
1489 f,
1490 ) == f(a)
1491 }
1492
1493 #[quickcheck]
1495 fn monad_right_identity(
1496 first: String,
1497 second: i32,
1498 ) -> bool {
1499 let m = (first, second);
1500 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1501 m.clone(),
1502 pure::<Tuple2FirstAppliedBrand<String>, _>,
1503 ) == m
1504 }
1505
1506 #[quickcheck]
1508 fn monad_associativity(
1509 first: String,
1510 second: i32,
1511 ) -> bool {
1512 let m = (first, second);
1513 let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
1514 let g = |x: i32| ("g".to_string(), x.wrapping_add(1));
1515 bind::<Tuple2FirstAppliedBrand<String>, _, _>(
1516 bind::<Tuple2FirstAppliedBrand<String>, _, _>(m.clone(), f),
1517 g,
1518 ) == bind::<Tuple2FirstAppliedBrand<String>, _, _>(m, |x| {
1519 bind::<Tuple2FirstAppliedBrand<String>, _, _>(f(x), g)
1520 })
1521 }
1522
1523 #[quickcheck]
1528 fn monad_rec_first_identity(x: i32) -> bool {
1529 tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
1530 |a| (String::new(), ControlFlow::Break(a)),
1531 x,
1532 ) == pure::<Tuple2FirstAppliedBrand<String>, _>(x)
1533 }
1534
1535 #[test]
1537 fn monad_rec_first_accumulation() {
1538 let result = tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
1539 |n: i32| {
1540 if n < 3 {
1541 (format!("{n},"), ControlFlow::Continue(n + 1))
1542 } else {
1543 (format!("{n}"), ControlFlow::Break(n))
1544 }
1545 },
1546 0,
1547 );
1548 assert_eq!(result, ("0,1,2,3".to_string(), 3));
1549 }
1550
1551 #[test]
1553 fn monad_rec_first_stack_safety() {
1554 let iterations: i64 = 200_000;
1555 let result = tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
1556 |acc| {
1557 if acc < iterations {
1558 (String::new(), ControlFlow::Continue(acc + 1))
1559 } else {
1560 (String::new(), ControlFlow::Break(acc))
1561 }
1562 },
1563 0i64,
1564 );
1565 assert_eq!(result, (String::new(), iterations));
1566 }
1567
1568 #[quickcheck]
1573 fn monad_rec_second_identity(x: i32) -> bool {
1574 tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
1575 |a| (ControlFlow::Break(a), String::new()),
1576 x,
1577 ) == pure::<Tuple2SecondAppliedBrand<String>, _>(x)
1578 }
1579
1580 #[test]
1582 fn monad_rec_second_accumulation() {
1583 let result = tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
1584 |n: i32| {
1585 if n < 3 {
1586 (ControlFlow::Continue(n + 1), format!("{n},"))
1587 } else {
1588 (ControlFlow::Break(n), format!("{n}"))
1589 }
1590 },
1591 0,
1592 );
1593 assert_eq!(result, (3, "0,1,2,3".to_string()));
1594 }
1595
1596 #[test]
1598 fn monad_rec_second_stack_safety() {
1599 let iterations: i64 = 200_000;
1600 let result = tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
1601 |acc| {
1602 if acc < iterations {
1603 (ControlFlow::Continue(acc + 1), String::new())
1604 } else {
1605 (ControlFlow::Break(acc), String::new())
1606 }
1607 },
1608 0i64,
1609 );
1610 assert_eq!(result, (iterations, String::new()));
1611 }
1612}