1#[fp_macros::document_module]
20mod inner {
21 use {
22 crate::{
23 Apply,
24 brands::{
25 StepBrand,
26 StepDoneAppliedBrand,
27 StepLoopAppliedBrand,
28 },
29 classes::{
30 Applicative,
31 ApplyFirst,
32 ApplySecond,
33 Bifoldable,
34 Bifunctor,
35 Bitraversable,
36 CloneableFn,
37 Foldable,
38 Functor,
39 Lift,
40 Monoid,
41 ParFoldable,
42 Pointed,
43 Semiapplicative,
44 Semimonad,
45 SendCloneableFn,
46 Traversable,
47 },
48 impl_kind,
49 kinds::*,
50 },
51 fp_macros::*,
52 };
53
54 #[document_type_parameters(
69 r#"The "loop" type - when we return `Loop(a)`, we continue with `a`."#,
70 r#"The "done" type - when we return `Done(b)`, we're finished."#
71 )]
72 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
79 pub enum Step<A, B> {
80 Loop(A),
82 Done(B),
84 }
85
86 #[document_type_parameters(
87 r#"The "loop" type - when we return `Loop(a)`, we continue with `a`."#,
88 r#"The "done" type - when we return `Done(b)`, we're finished."#
89 )]
90 #[document_parameters("The step value.")]
91 impl<A, B> Step<A, B> {
92 #[document_signature]
94 #[document_returns("`true` if the step is a loop, `false` otherwise.")]
96 #[inline]
98 #[document_examples]
99 pub fn is_loop(&self) -> bool {
107 matches!(self, Step::Loop(_))
108 }
109
110 #[document_signature]
112 #[document_returns("`true` if the step is done, `false` otherwise.")]
114 #[inline]
116 #[document_examples]
117 pub fn is_done(&self) -> bool {
125 matches!(self, Step::Done(_))
126 }
127
128 #[document_signature]
130 #[document_type_parameters("The new loop type.")]
132 #[document_parameters("The function to apply to the loop value.")]
134 #[document_returns("A new `Step` with the loop value transformed.")]
136 #[document_examples]
138 pub fn map_loop<C>(
147 self,
148 f: impl FnOnce(A) -> C,
149 ) -> Step<C, B> {
150 match self {
151 Step::Loop(a) => Step::Loop(f(a)),
152 Step::Done(b) => Step::Done(b),
153 }
154 }
155
156 #[document_signature]
158 #[document_type_parameters("The new done type.")]
160 #[document_parameters("The function to apply to the done value.")]
162 #[document_returns("A new `Step` with the done value transformed.")]
164 #[document_examples]
166 pub fn map_done<C>(
175 self,
176 f: impl FnOnce(B) -> C,
177 ) -> Step<A, C> {
178 match self {
179 Step::Loop(a) => Step::Loop(a),
180 Step::Done(b) => Step::Done(f(b)),
181 }
182 }
183
184 #[document_signature]
186 #[document_type_parameters("The new loop type.", "The new done type.")]
188 #[document_parameters(
190 "The function to apply to the loop value.",
191 "The function to apply to the done value."
192 )]
193 #[document_returns("A new `Step` with both values transformed.")]
195 #[document_examples]
196 pub fn bimap<C, D>(
205 self,
206 f: impl FnOnce(A) -> C,
207 g: impl FnOnce(B) -> D,
208 ) -> Step<C, D> {
209 match self {
210 Step::Loop(a) => Step::Loop(f(a)),
211 Step::Done(b) => Step::Done(g(b)),
212 }
213 }
214
215 #[document_signature]
219 #[document_type_parameters("The accumulator type.")]
221 #[document_parameters(
223 "The step function for the Loop variant.",
224 "The step function for the Done variant.",
225 "The initial accumulator."
226 )]
227 #[document_returns("The result of folding.")]
229 #[document_examples]
231 pub fn bi_fold_right<C>(
239 self,
240 f: impl FnOnce(A, C) -> C,
241 g: impl FnOnce(B, C) -> C,
242 z: C,
243 ) -> C {
244 match self {
245 Step::Loop(a) => f(a, z),
246 Step::Done(b) => g(b, z),
247 }
248 }
249
250 #[document_signature]
254 #[document_type_parameters("The accumulator type.")]
256 #[document_parameters(
258 "The step function for the Loop variant.",
259 "The step function for the Done variant.",
260 "The initial accumulator."
261 )]
262 #[document_returns("The result of folding.")]
264 #[document_examples]
266 pub fn bi_fold_left<C>(
274 self,
275 f: impl FnOnce(C, A) -> C,
276 g: impl FnOnce(C, B) -> C,
277 z: C,
278 ) -> C {
279 match self {
280 Step::Loop(a) => f(z, a),
281 Step::Done(b) => g(z, b),
282 }
283 }
284
285 #[document_signature]
289 #[document_type_parameters("The monoid type.")]
291 #[document_parameters(
293 "The function mapping the Loop value to the monoid.",
294 "The function mapping the Done value to the monoid."
295 )]
296 #[document_returns("The monoid value.")]
298 #[document_examples]
300 pub fn bi_fold_map<M>(
308 self,
309 f: impl FnOnce(A) -> M,
310 g: impl FnOnce(B) -> M,
311 ) -> M {
312 match self {
313 Step::Loop(a) => f(a),
314 Step::Done(b) => g(b),
315 }
316 }
317
318 #[document_signature]
323 #[document_type_parameters("The accumulator type.")]
325 #[document_parameters(
327 "The function to apply to the Done value and the accumulator.",
328 "The initial accumulator."
329 )]
330 #[document_returns("The result of folding.")]
332 #[document_examples]
334 pub fn fold_right<C>(
342 self,
343 f: impl FnOnce(B, C) -> C,
344 initial: C,
345 ) -> C {
346 match self {
347 Step::Loop(_) => initial,
348 Step::Done(b) => f(b, initial),
349 }
350 }
351
352 #[document_signature]
357 #[document_type_parameters("The accumulator type.")]
359 #[document_parameters(
361 "The function to apply to the accumulator and the Done value.",
362 "The initial accumulator."
363 )]
364 #[document_returns("The result of folding.")]
366 #[document_examples]
368 pub fn fold_left<C>(
376 self,
377 f: impl FnOnce(C, B) -> C,
378 initial: C,
379 ) -> C {
380 match self {
381 Step::Loop(_) => initial,
382 Step::Done(b) => f(initial, b),
383 }
384 }
385
386 #[document_signature]
391 #[document_type_parameters("The monoid type.")]
393 #[document_parameters("The mapping function.")]
395 #[document_returns("The monoid value.")]
397 #[document_examples]
399 pub fn fold_map<M: Monoid>(
407 self,
408 f: impl FnOnce(B) -> M,
409 ) -> M {
410 match self {
411 Step::Loop(_) => M::empty(),
412 Step::Done(b) => f(b),
413 }
414 }
415
416 #[document_signature]
421 #[document_type_parameters("The type of the resulting Done value.")]
423 #[document_parameters("The function to apply to the Done value.")]
425 #[document_returns("The result of the computation.")]
427 #[document_examples]
429 pub fn bind<C>(
438 self,
439 f: impl FnOnce(B) -> Step<A, C>,
440 ) -> Step<A, C> {
441 match self {
442 Step::Loop(a) => Step::Loop(a),
443 Step::Done(b) => f(b),
444 }
445 }
446
447 #[document_signature]
452 #[document_type_parameters("The type of the resulting Loop value.")]
454 #[document_parameters("The function to apply to the Loop value.")]
456 #[document_returns("The result of the computation.")]
458 #[document_examples]
460 pub fn bind_loop<C>(
469 self,
470 f: impl FnOnce(A) -> Step<C, B>,
471 ) -> Step<C, B> {
472 match self {
473 Step::Loop(a) => f(a),
474 Step::Done(b) => Step::Done(b),
475 }
476 }
477 }
478
479 #[document_type_parameters(
480 "The lifetime of the values.",
481 "The type of the Loop value.",
482 "The type of the Done value."
483 )]
484 #[document_parameters("The step instance.")]
485 impl<'a, A: 'a, B: 'a> Step<A, B> {
486 #[document_signature]
490 #[document_type_parameters(
492 "The output type for the Loop value.",
493 "The output type for the Done value.",
494 "The applicative context."
495 )]
496 #[document_parameters(
498 "The function for the Loop value.",
499 "The function for the Done value."
500 )]
501 #[document_returns("The transformed step wrapped in the applicative context.")]
503 #[document_examples]
505 pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
517 self,
518 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
519 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
520 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Step<C, D>>)
521 where
522 Step<C, D>: Clone, {
523 match self {
524 Step::Loop(a) => F::map(|c| Step::Loop(c), f(a)),
525 Step::Done(b) => F::map(|d| Step::Done(d), g(b)),
526 }
527 }
528 }
529
530 impl_kind! {
531 for StepBrand {
532 type Of<A, B> = Step<A, B>;
533 }
534 }
535
536 impl_kind! {
537 for StepBrand {
538 type Of<'a, A: 'a, B: 'a>: 'a = Step<A, B>;
539 }
540 }
541
542 impl Bifunctor for StepBrand {
543 #[document_signature]
547 #[document_type_parameters(
549 "The lifetime of the values.",
550 "The type of the loop value.",
551 "The type of the mapped loop value.",
552 "The type of the done value.",
553 "The type of the mapped done value."
554 )]
555 #[document_parameters(
557 "The function to apply to the loop value.",
558 "The function to apply to the done value.",
559 "The step to map over."
560 )]
561 #[document_returns("A new step containing the mapped values.")]
563 #[document_examples]
564 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
577 f: impl Fn(A) -> B + 'a,
578 g: impl Fn(C) -> D + 'a,
579 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
580 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
581 p.bimap(f, g)
582 }
583 }
584
585 impl Bifoldable for StepBrand {
586 #[document_signature]
590 #[document_type_parameters(
592 "The lifetime of the values.",
593 "The brand of the cloneable function to use.",
594 "The type of the Loop value.",
595 "The type of the Done value.",
596 "The accumulator type."
597 )]
598 #[document_parameters(
600 "The step function for the Loop variant.",
601 "The step function for the Done variant.",
602 "The initial accumulator.",
603 "The step to fold."
604 )]
605 #[document_returns("The folded result.")]
607 #[document_examples]
608 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
623 f: impl Fn(A, C) -> C + 'a,
624 g: impl Fn(B, C) -> C + 'a,
625 z: C,
626 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
627 ) -> C {
628 p.bi_fold_right(f, g, z)
629 }
630
631 #[document_signature]
635 #[document_type_parameters(
637 "The lifetime of the values.",
638 "The brand of the cloneable function to use.",
639 "The type of the Loop value.",
640 "The type of the Done value.",
641 "The accumulator type."
642 )]
643 #[document_parameters(
645 "The step function for the Loop variant.",
646 "The step function for the Done variant.",
647 "The initial accumulator.",
648 "The step to fold."
649 )]
650 #[document_returns("The folded result.")]
652 #[document_examples]
653 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
668 f: impl Fn(C, A) -> C + 'a,
669 g: impl Fn(C, B) -> C + 'a,
670 z: C,
671 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
672 ) -> C {
673 p.bi_fold_left(f, g, z)
674 }
675
676 #[document_signature]
680 #[document_type_parameters(
682 "The lifetime of the values.",
683 "The brand of the cloneable function to use.",
684 "The type of the Loop value.",
685 "The type of the Done value.",
686 "The monoid type."
687 )]
688 #[document_parameters(
690 "The function mapping the Loop value to the monoid.",
691 "The function mapping the Done value to the monoid.",
692 "The step to fold."
693 )]
694 #[document_returns("The monoid value.")]
696 #[document_examples]
697 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
716 f: impl Fn(A) -> M + 'a,
717 g: impl Fn(B) -> M + 'a,
718 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
719 ) -> M
720 where
721 M: Monoid + 'a, {
722 p.bi_fold_map(f, g)
723 }
724 }
725
726 impl Bitraversable for StepBrand {
727 #[document_signature]
732 #[document_type_parameters(
734 "The lifetime of the values.",
735 "The type of the Loop value.",
736 "The type of the Done value.",
737 "The output type for Loop.",
738 "The output type for Done.",
739 "The applicative context."
740 )]
741 #[document_parameters(
743 "The function applied to the Loop value.",
744 "The function applied to the Done value.",
745 "The step to traverse."
746 )]
747 #[document_returns("The transformed step wrapped in the applicative context.")]
749 #[document_examples]
750 fn bi_traverse<
769 'a,
770 A: 'a + Clone,
771 B: 'a + Clone,
772 C: 'a + Clone,
773 D: 'a + Clone,
774 F: Applicative,
775 >(
776 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
777 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
778 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
779 ) -> 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>)>)
780 {
781 p.bi_traverse::<C, D, F>(f, g)
782 }
783 }
784
785 impl_kind! {
788 impl<LoopType: 'static> for StepLoopAppliedBrand<LoopType> {
789 type Of<'a, B: 'a>: 'a = Step<LoopType, B>;
790 }
791 }
792
793 #[document_type_parameters("The loop type.")]
794 impl<LoopType: 'static> Functor for StepLoopAppliedBrand<LoopType> {
795 #[document_signature]
799 #[document_type_parameters(
801 "The lifetime of the values.",
802 "The type of the done value.",
803 "The type of the result of applying the function."
804 )]
805 #[document_parameters("The function to apply to the done value.", "The step to map over.")]
807 #[document_returns(
809 "A new step containing the result of applying the function to the done value."
810 )]
811 #[document_examples]
813 fn map<'a, A: 'a, B: 'a>(
827 func: impl Fn(A) -> B + 'a,
828 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
829 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
830 fa.map_done(func)
831 }
832 }
833
834 #[document_type_parameters("The loop type.")]
835 impl<LoopType: Clone + 'static> Lift for StepLoopAppliedBrand<LoopType> {
836 #[document_signature]
840 #[document_type_parameters(
842 "The lifetime of the values.",
843 "The type of the first value.",
844 "The type of the second value.",
845 "The type of the result."
846 )]
847 #[document_parameters(
849 "The binary function to apply.",
850 "The first step.",
851 "The second step."
852 )]
853 #[document_returns(
855 "`Done(f(a, b))` if both steps are `Done`, otherwise the first loop encountered."
856 )]
857 #[document_examples]
858 fn lift2<'a, A, B, C>(
884 func: impl Fn(A, B) -> C + 'a,
885 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
886 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
887 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
888 where
889 A: Clone + 'a,
890 B: Clone + 'a,
891 C: 'a, {
892 match (fa, fb) {
893 (Step::Done(a), Step::Done(b)) => Step::Done(func(a, b)),
894 (Step::Loop(e), _) => Step::Loop(e),
895 (_, Step::Loop(e)) => Step::Loop(e),
896 }
897 }
898 }
899
900 #[document_type_parameters("The loop type.")]
901 impl<LoopType: 'static> Pointed for StepLoopAppliedBrand<LoopType> {
902 #[document_signature]
906 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
908 #[document_parameters("The value to wrap.")]
910 #[document_returns("`Done(a)`.")]
912 #[document_examples]
914 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
925 Step::Done(a)
926 }
927 }
928
929 #[document_type_parameters("The loop type.")]
930 impl<LoopType: Clone + 'static> ApplyFirst for StepLoopAppliedBrand<LoopType> {}
931
932 #[document_type_parameters("The loop type.")]
933 impl<LoopType: Clone + 'static> ApplySecond for StepLoopAppliedBrand<LoopType> {}
934
935 #[document_type_parameters("The loop type.")]
936 impl<LoopType: Clone + 'static> Semiapplicative for StepLoopAppliedBrand<LoopType> {
937 #[document_signature]
941 #[document_type_parameters(
943 "The lifetime of the values.",
944 "The brand of the cloneable function wrapper.",
945 "The type of the input value.",
946 "The type of the output value."
947 )]
948 #[document_parameters(
950 "The step containing the function.",
951 "The step containing the value."
952 )]
953 #[document_returns(
955 "`Done(f(a))` if both are `Done`, otherwise the first loop encountered."
956 )]
957 #[document_examples]
958 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
974 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
975 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
976 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
977 match (ff, fa) {
978 (Step::Done(f), Step::Done(a)) => Step::Done(f(a)),
979 (Step::Loop(e), _) => Step::Loop(e),
980 (_, Step::Loop(e)) => Step::Loop(e),
981 }
982 }
983 }
984
985 #[document_type_parameters("The loop type.")]
986 impl<LoopType: Clone + 'static> Semimonad for StepLoopAppliedBrand<LoopType> {
987 #[document_signature]
991 #[document_type_parameters(
993 "The lifetime of the values.",
994 "The type of the result of the first computation.",
995 "The type of the result of the second computation."
996 )]
997 #[document_parameters(
999 "The first step.",
1000 "The function to apply to the value inside the step."
1001 )]
1002 #[document_returns(
1004 "The result of applying `f` to the value if `ma` is `Done`, otherwise the original loop."
1005 )]
1006 #[document_examples]
1007 fn bind<'a, A: 'a, B: 'a>(
1021 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1022 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1023 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1024 ma.bind(func)
1025 }
1026 }
1027
1028 #[document_type_parameters("The loop type.")]
1029 impl<LoopType: 'static> Foldable for StepLoopAppliedBrand<LoopType> {
1030 #[document_signature]
1034 #[document_type_parameters(
1036 "The lifetime of the values.",
1037 "The brand of the cloneable function to use.",
1038 "The type of the elements in the structure.",
1039 "The type of the accumulator."
1040 )]
1041 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1043 #[document_returns("`func(a, initial)` if `fa` is `Done(a)`, otherwise `initial`.")]
1045 #[document_examples]
1047 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1069 func: impl Fn(A, B) -> B + 'a,
1070 initial: B,
1071 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1072 ) -> B
1073 where
1074 FnBrand: CloneableFn + 'a, {
1075 fa.fold_right(func, initial)
1076 }
1077
1078 #[document_signature]
1082 #[document_type_parameters(
1084 "The lifetime of the values.",
1085 "The brand of the cloneable function to use.",
1086 "The type of the elements in the structure.",
1087 "The type of the accumulator."
1088 )]
1089 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1091 #[document_returns("`func(initial, a)` if `fa` is `Done(a)`, otherwise `initial`.")]
1093 #[document_examples]
1095 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1117 func: impl Fn(B, A) -> B + 'a,
1118 initial: B,
1119 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1120 ) -> B
1121 where
1122 FnBrand: CloneableFn + 'a, {
1123 fa.fold_left(func, initial)
1124 }
1125
1126 #[document_signature]
1130 #[document_type_parameters(
1132 "The lifetime of the values.",
1133 "The brand of the cloneable function to use.",
1134 "The type of the elements in the structure.",
1135 "The type of the monoid."
1136 )]
1137 #[document_parameters("The mapping function.", "The step to fold.")]
1139 #[document_returns("`func(a)` if `fa` is `Done(a)`, otherwise `M::empty()`.")]
1141 #[document_examples]
1143 fn fold_map<'a, FnBrand, A: 'a, M>(
1167 func: impl Fn(A) -> M + 'a,
1168 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1169 ) -> M
1170 where
1171 M: Monoid + 'a,
1172 FnBrand: CloneableFn + 'a, {
1173 fa.fold_map(func)
1174 }
1175 }
1176
1177 #[document_type_parameters("The loop type.")]
1178 impl<LoopType: Clone + 'static> Traversable for StepLoopAppliedBrand<LoopType> {
1179 #[document_signature]
1183 #[document_type_parameters(
1185 "The lifetime of the values.",
1186 "The type of the elements in the traversable structure.",
1187 "The type of the elements in the resulting traversable structure.",
1188 "The applicative context."
1189 )]
1190 #[document_parameters("The function to apply.", "The step to traverse.")]
1192 #[document_returns("The step wrapped in the applicative context.")]
1194 #[document_examples]
1196 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1217 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1218 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1219 ) -> 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>)>)
1220 where
1221 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1222 match ta {
1223 Step::Done(a) => F::map(|b| Step::Done(b), func(a)),
1224 Step::Loop(e) => F::pure(Step::Loop(e)),
1225 }
1226 }
1227
1228 #[document_signature]
1232 #[document_type_parameters(
1234 "The lifetime of the values.",
1235 "The type of the elements in the traversable structure.",
1236 "The applicative context."
1237 )]
1238 #[document_parameters("The step containing the applicative value.")]
1240 #[document_returns("The step wrapped in the applicative context.")]
1242 #[document_examples]
1244 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1262 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>)>)
1263 ) -> 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>)>)
1264 where
1265 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1266 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1267 match ta {
1268 Step::Done(fa) => F::map(|a| Step::Done(a), fa),
1269 Step::Loop(e) => F::pure(Step::Loop(e)),
1270 }
1271 }
1272 }
1273
1274 #[document_type_parameters("The loop type.")]
1275 impl<LoopType: 'static> ParFoldable for StepLoopAppliedBrand<LoopType> {
1276 #[document_signature]
1280 #[document_type_parameters(
1282 "The lifetime of the values.",
1283 "The brand of the cloneable function wrapper.",
1284 "The element type.",
1285 "The monoid type."
1286 )]
1287 #[document_parameters(
1289 "The thread-safe function to map each element to a monoid.",
1290 "The step to fold."
1291 )]
1292 #[document_returns("The combined monoid value.")]
1294 #[document_examples]
1295 fn par_fold_map<'a, FnBrand, A, M>(
1318 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1319 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1320 ) -> M
1321 where
1322 FnBrand: 'a + SendCloneableFn,
1323 A: 'a + Clone + Send + Sync,
1324 M: Monoid + Send + Sync + 'a, {
1325 match fa {
1326 Step::Done(a) => func(a),
1327 Step::Loop(_) => M::empty(),
1328 }
1329 }
1330
1331 #[document_signature]
1335 #[document_type_parameters(
1337 "The lifetime of the values.",
1338 "The brand of the cloneable function wrapper.",
1339 "The element type.",
1340 "The accumulator type."
1341 )]
1342 #[document_parameters(
1344 "The thread-safe function to apply to each element and the accumulator.",
1345 "The initial value.",
1346 "The step to fold."
1347 )]
1348 #[document_returns("The final accumulator value.")]
1350 #[document_examples]
1351 fn par_fold_right<'a, FnBrand, A, B>(
1368 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1369 initial: B,
1370 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1371 ) -> B
1372 where
1373 FnBrand: 'a + SendCloneableFn,
1374 A: 'a + Clone + Send + Sync,
1375 B: Send + Sync + 'a, {
1376 match fa {
1377 Step::Done(a) => func((a, initial)),
1378 Step::Loop(_) => initial,
1379 }
1380 }
1381 }
1382
1383 impl_kind! {
1386 impl<DoneType: 'static> for StepDoneAppliedBrand<DoneType> {
1387 type Of<'a, A: 'a>: 'a = Step<A, DoneType>;
1388 }
1389 }
1390
1391 #[document_type_parameters("The done type.")]
1392 impl<DoneType: 'static> Functor for StepDoneAppliedBrand<DoneType> {
1393 #[document_signature]
1397 #[document_type_parameters(
1399 "The lifetime of the values.",
1400 "The type of the loop value.",
1401 "The type of the result of applying the function."
1402 )]
1403 #[document_parameters("The function to apply to the loop value.", "The step to map over.")]
1405 #[document_returns(
1407 "A new step containing the result of applying the function to the loop value."
1408 )]
1409 #[document_examples]
1411 fn map<'a, A: 'a, B: 'a>(
1425 func: impl Fn(A) -> B + 'a,
1426 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1427 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1428 fa.map_loop(func)
1429 }
1430 }
1431
1432 #[document_type_parameters("The done type.")]
1433 impl<DoneType: Clone + 'static> Lift for StepDoneAppliedBrand<DoneType> {
1434 #[document_signature]
1438 #[document_type_parameters(
1440 "The lifetime of the values.",
1441 "The type of the first loop value.",
1442 "The type of the second loop value.",
1443 "The type of the result loop value."
1444 )]
1445 #[document_parameters(
1447 "The binary function to apply to the loops.",
1448 "The first step.",
1449 "The second step."
1450 )]
1451 #[document_returns(
1453 "`Loop(f(a, b))` if both steps are `Loop`, otherwise the first done encountered."
1454 )]
1455 #[document_examples]
1456 fn lift2<'a, A, B, C>(
1482 func: impl Fn(A, B) -> C + 'a,
1483 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1484 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1485 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1486 where
1487 A: Clone + 'a,
1488 B: Clone + 'a,
1489 C: 'a, {
1490 match (fa, fb) {
1491 (Step::Loop(a), Step::Loop(b)) => Step::Loop(func(a, b)),
1492 (Step::Done(t), _) => Step::Done(t),
1493 (_, Step::Done(t)) => Step::Done(t),
1494 }
1495 }
1496 }
1497
1498 #[document_type_parameters("The done type.")]
1499 impl<DoneType: 'static> Pointed for StepDoneAppliedBrand<DoneType> {
1500 #[document_signature]
1504 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1506 #[document_parameters("The value to wrap.")]
1508 #[document_returns("`Loop(a)`.")]
1510 #[document_examples]
1512 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1523 Step::Loop(a)
1524 }
1525 }
1526
1527 #[document_type_parameters("The done type.")]
1528 impl<DoneType: Clone + 'static> ApplyFirst for StepDoneAppliedBrand<DoneType> {}
1529
1530 #[document_type_parameters("The done type.")]
1531 impl<DoneType: Clone + 'static> ApplySecond for StepDoneAppliedBrand<DoneType> {}
1532
1533 #[document_type_parameters("The done type.")]
1534 impl<DoneType: Clone + 'static> Semiapplicative for StepDoneAppliedBrand<DoneType> {
1535 #[document_signature]
1539 #[document_type_parameters(
1541 "The lifetime of the values.",
1542 "The brand of the cloneable function wrapper.",
1543 "The type of the input value.",
1544 "The type of the output value."
1545 )]
1546 #[document_parameters(
1548 "The step containing the function (in Loop).",
1549 "The step containing the value (in Loop)."
1550 )]
1551 #[document_returns(
1553 "`Loop(f(a))` if both are `Loop`, otherwise the first done encountered."
1554 )]
1555 #[document_examples]
1556 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1572 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1573 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1574 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1575 match (ff, fa) {
1576 (Step::Loop(f), Step::Loop(a)) => Step::Loop(f(a)),
1577 (Step::Done(t), _) => Step::Done(t),
1578 (_, Step::Done(t)) => Step::Done(t),
1579 }
1580 }
1581 }
1582
1583 #[document_type_parameters("The done type.")]
1584 impl<DoneType: Clone + 'static> Semimonad for StepDoneAppliedBrand<DoneType> {
1585 #[document_signature]
1589 #[document_type_parameters(
1591 "The lifetime of the values.",
1592 "The type of the result of the first computation.",
1593 "The type of the result of the second computation."
1594 )]
1595 #[document_parameters("The first step.", "The function to apply to the loop value.")]
1597 #[document_returns(
1599 "The result of applying `f` to the loop if `ma` is `Loop`, otherwise the original done."
1600 )]
1601 #[document_examples]
1603 fn bind<'a, A: 'a, B: 'a>(
1617 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1618 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1619 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1620 ma.bind_loop(func)
1621 }
1622 }
1623
1624 #[document_type_parameters("The done type.")]
1625 impl<DoneType: 'static> Foldable for StepDoneAppliedBrand<DoneType> {
1626 #[document_signature]
1630 #[document_type_parameters(
1632 "The lifetime of the values.",
1633 "The brand of the cloneable function to use.",
1634 "The type of the elements in the structure.",
1635 "The type of the accumulator."
1636 )]
1637 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1639 #[document_returns("`func(a, initial)` if `fa` is `Loop(a)`, otherwise `initial`.")]
1641 #[document_examples]
1643 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1669 func: impl Fn(A, B) -> B + 'a,
1670 initial: B,
1671 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1672 ) -> B
1673 where
1674 FnBrand: CloneableFn + 'a, {
1675 match fa {
1676 Step::Loop(e) => func(e, initial),
1677 Step::Done(_) => initial,
1678 }
1679 }
1680
1681 #[document_signature]
1685 #[document_type_parameters(
1687 "The lifetime of the values.",
1688 "The brand of the cloneable function to use.",
1689 "The type of the elements in the structure.",
1690 "The type of the accumulator."
1691 )]
1692 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1694 #[document_returns("`func(initial, a)` if `fa` is `Loop(a)`, otherwise `initial`.")]
1696 #[document_examples]
1698 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1724 func: impl Fn(B, A) -> B + 'a,
1725 initial: B,
1726 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1727 ) -> B
1728 where
1729 FnBrand: CloneableFn + 'a, {
1730 match fa {
1731 Step::Loop(e) => func(initial, e),
1732 Step::Done(_) => initial,
1733 }
1734 }
1735
1736 #[document_signature]
1740 #[document_type_parameters(
1742 "The lifetime of the values.",
1743 "The brand of the cloneable function to use.",
1744 "The type of the elements in the structure.",
1745 "The type of the monoid."
1746 )]
1747 #[document_parameters("The mapping function.", "The step to fold.")]
1749 #[document_returns("`func(a)` if `fa` is `Loop(a)`, otherwise `M::empty()`.")]
1751 #[document_examples]
1753 fn fold_map<'a, FnBrand, A: 'a, M>(
1777 func: impl Fn(A) -> M + 'a,
1778 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1779 ) -> M
1780 where
1781 M: Monoid + 'a,
1782 FnBrand: CloneableFn + 'a, {
1783 match fa {
1784 Step::Loop(e) => func(e),
1785 Step::Done(_) => M::empty(),
1786 }
1787 }
1788 }
1789
1790 #[document_type_parameters("The done type.")]
1791 impl<DoneType: Clone + 'static> Traversable for StepDoneAppliedBrand<DoneType> {
1792 #[document_signature]
1796 #[document_type_parameters(
1798 "The lifetime of the values.",
1799 "The type of the elements in the traversable structure.",
1800 "The type of the elements in the resulting traversable structure.",
1801 "The applicative context."
1802 )]
1803 #[document_parameters("The function to apply.", "The step to traverse.")]
1805 #[document_returns("The step wrapped in the applicative context.")]
1807 #[document_examples]
1809 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1830 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1831 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1832 ) -> 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>)>)
1833 where
1834 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1835 match ta {
1836 Step::Loop(e) => F::map(|b| Step::Loop(b), func(e)),
1837 Step::Done(t) => F::pure(Step::Done(t)),
1838 }
1839 }
1840
1841 #[document_signature]
1845 #[document_type_parameters(
1847 "The lifetime of the values.",
1848 "The type of the elements in the traversable structure.",
1849 "The applicative context."
1850 )]
1851 #[document_parameters("The step containing the applicative value.")]
1853 #[document_returns("The step wrapped in the applicative context.")]
1855 #[document_examples]
1857 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1875 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>)>)
1876 ) -> 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>)>)
1877 where
1878 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1879 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1880 match ta {
1881 Step::Loop(fe) => F::map(|e| Step::Loop(e), fe),
1882 Step::Done(t) => F::pure(Step::Done(t)),
1883 }
1884 }
1885 }
1886
1887 #[document_type_parameters("The done type.")]
1888 impl<DoneType: 'static> ParFoldable for StepDoneAppliedBrand<DoneType> {
1889 #[document_signature]
1893 #[document_type_parameters(
1895 "The lifetime of the values.",
1896 "The brand of the cloneable function wrapper.",
1897 "The element type.",
1898 "The monoid type."
1899 )]
1900 #[document_parameters(
1902 "The thread-safe function to map each element to a monoid.",
1903 "The step to fold."
1904 )]
1905 #[document_returns("The combined monoid value.")]
1907 #[document_examples]
1908 fn par_fold_map<'a, FnBrand, A, M>(
1931 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1932 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1933 ) -> M
1934 where
1935 FnBrand: 'a + SendCloneableFn,
1936 A: 'a + Clone + Send + Sync,
1937 M: Monoid + Send + Sync + 'a, {
1938 match fa {
1939 Step::Loop(e) => func(e),
1940 Step::Done(_) => M::empty(),
1941 }
1942 }
1943
1944 #[document_signature]
1948 #[document_type_parameters(
1950 "The lifetime of the values.",
1951 "The brand of the cloneable function wrapper.",
1952 "The element type.",
1953 "The accumulator type."
1954 )]
1955 #[document_parameters(
1957 "The thread-safe function to apply to each element and the accumulator.",
1958 "The initial value.",
1959 "The step to fold."
1960 )]
1961 #[document_returns("The final accumulator value.")]
1963 #[document_examples]
1964 fn par_fold_right<'a, FnBrand, A, B>(
1981 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1982 initial: B,
1983 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1984 ) -> B
1985 where
1986 FnBrand: 'a + SendCloneableFn,
1987 A: 'a + Clone + Send + Sync,
1988 B: Send + Sync + 'a, {
1989 match fa {
1990 Step::Loop(e) => func((e, initial)),
1991 Step::Done(_) => initial,
1992 }
1993 }
1994 }
1995}
1996pub use inner::*;
1997
1998#[cfg(test)]
1999mod tests {
2000 use {
2001 super::*,
2002 crate::{
2003 brands::*,
2004 classes::{
2005 bifunctor::*,
2006 foldable::*,
2007 functor::*,
2008 lift::*,
2009 par_foldable::*,
2010 pointed::*,
2011 semiapplicative::*,
2012 semimonad::*,
2013 traversable::*,
2014 },
2015 functions::*,
2016 },
2017 quickcheck::{
2018 Arbitrary,
2019 Gen,
2020 },
2021 quickcheck_macros::quickcheck,
2022 };
2023
2024 impl<A: Arbitrary, B: Arbitrary> Arbitrary for Step<A, B> {
2025 fn arbitrary(g: &mut Gen) -> Self {
2026 if bool::arbitrary(g) {
2027 Step::Loop(A::arbitrary(g))
2028 } else {
2029 Step::Done(B::arbitrary(g))
2030 }
2031 }
2032 }
2033
2034 #[test]
2038 fn test_is_loop() {
2039 let step: Step<i32, i32> = Step::Loop(1);
2040 assert!(step.is_loop());
2041 assert!(!step.is_done());
2042 }
2043
2044 #[test]
2048 fn test_is_done() {
2049 let step: Step<i32, i32> = Step::Done(1);
2050 assert!(step.is_done());
2051 assert!(!step.is_loop());
2052 }
2053
2054 #[test]
2058 fn test_map_loop() {
2059 let step: Step<i32, i32> = Step::Loop(1);
2060 let mapped = step.map_loop(|x| x + 1);
2061 assert_eq!(mapped, Step::Loop(2));
2062
2063 let done: Step<i32, i32> = Step::Done(1);
2064 let mapped_done = done.map_loop(|x| x + 1);
2065 assert_eq!(mapped_done, Step::Done(1));
2066 }
2067
2068 #[test]
2072 fn test_map_done() {
2073 let step: Step<i32, i32> = Step::Done(1);
2074 let mapped = step.map_done(|x| x + 1);
2075 assert_eq!(mapped, Step::Done(2));
2076
2077 let loop_step: Step<i32, i32> = Step::Loop(1);
2078 let mapped_loop = loop_step.map_done(|x| x + 1);
2079 assert_eq!(mapped_loop, Step::Loop(1));
2080 }
2081
2082 #[test]
2086 fn test_bimap() {
2087 let step: Step<i32, i32> = Step::Loop(1);
2088 let mapped = step.bimap(|x| x + 1, |x| x * 2);
2089 assert_eq!(mapped, Step::Loop(2));
2090
2091 let done: Step<i32, i32> = Step::Done(1);
2092 let mapped_done = done.bimap(|x| x + 1, |x| x * 2);
2093 assert_eq!(mapped_done, Step::Done(2));
2094 }
2095
2096 #[test]
2098 fn test_functor_step_with_loop() {
2099 let step: Step<i32, i32> = Step::Done(5);
2100 assert_eq!(map::<StepLoopAppliedBrand<_>, _, _>(|x: i32| x * 2, step), Step::Done(10));
2101
2102 let loop_step: Step<i32, i32> = Step::Loop(5);
2103 assert_eq!(map::<StepLoopAppliedBrand<_>, _, _>(|x: i32| x * 2, loop_step), Step::Loop(5));
2104 }
2105
2106 #[test]
2108 fn test_functor_step_with_done() {
2109 let step: Step<i32, i32> = Step::Loop(5);
2110 assert_eq!(map::<StepDoneAppliedBrand<_>, _, _>(|x: i32| x * 2, step), Step::Loop(10));
2111
2112 let done_step: Step<i32, i32> = Step::Done(5);
2113 assert_eq!(map::<StepDoneAppliedBrand<_>, _, _>(|x: i32| x * 2, done_step), Step::Done(5));
2114 }
2115
2116 #[test]
2118 fn test_bifunctor_step() {
2119 let step: Step<i32, i32> = Step::Loop(5);
2120 assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b| b * 2, step), Step::Loop(6));
2121
2122 let done: Step<i32, i32> = Step::Done(5);
2123 assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b| b * 2, done), Step::Done(10));
2124 }
2125
2126 #[quickcheck]
2129 fn functor_identity_step_with_loop(x: Step<i32, i32>) -> bool {
2130 map::<StepLoopAppliedBrand<i32>, _, _>(identity, x) == x
2131 }
2132
2133 #[quickcheck]
2134 fn functor_composition_step_with_loop(x: Step<i32, i32>) -> bool {
2135 let f = |x: i32| x.wrapping_add(1);
2136 let g = |x: i32| x.wrapping_mul(2);
2137 map::<StepLoopAppliedBrand<i32>, _, _>(compose(f, g), x)
2138 == map::<StepLoopAppliedBrand<i32>, _, _>(
2139 f,
2140 map::<StepLoopAppliedBrand<i32>, _, _>(g, x),
2141 )
2142 }
2143
2144 #[quickcheck]
2147 fn functor_identity_step_with_done(x: Step<i32, i32>) -> bool {
2148 map::<StepDoneAppliedBrand<i32>, _, _>(identity, x) == x
2149 }
2150
2151 #[quickcheck]
2152 fn functor_composition_step_with_done(x: Step<i32, i32>) -> bool {
2153 let f = |x: i32| x.wrapping_add(1);
2154 let g = |x: i32| x.wrapping_mul(2);
2155 map::<StepDoneAppliedBrand<i32>, _, _>(compose(f, g), x)
2156 == map::<StepDoneAppliedBrand<i32>, _, _>(
2157 f,
2158 map::<StepDoneAppliedBrand<i32>, _, _>(g, x),
2159 )
2160 }
2161
2162 #[quickcheck]
2165 fn bifunctor_identity_step(x: Step<i32, i32>) -> bool {
2166 bimap::<StepBrand, _, _, _, _>(identity, identity, x) == x
2167 }
2168
2169 #[quickcheck]
2170 fn bifunctor_composition_step(x: Step<i32, i32>) -> bool {
2171 let f = |x: i32| x.wrapping_add(1);
2172 let g = |x: i32| x.wrapping_mul(2);
2173 let h = |x: i32| x.wrapping_sub(1);
2174 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
2175
2176 bimap::<StepBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
2177 == bimap::<StepBrand, _, _, _, _>(f, h, bimap::<StepBrand, _, _, _, _>(g, i, x))
2178 }
2179
2180 #[test]
2187 fn test_lift2_step_with_loop() {
2188 let s1: Step<i32, i32> = Step::Done(1);
2189 let s2: Step<i32, i32> = Step::Done(2);
2190 let s3: Step<i32, i32> = Step::Loop(3);
2191
2192 assert_eq!(
2193 lift2::<StepLoopAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s2),
2194 Step::Done(3)
2195 );
2196 assert_eq!(
2197 lift2::<StepLoopAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s3),
2198 Step::Loop(3)
2199 );
2200 }
2201
2202 #[test]
2207 fn test_lift2_step_with_done() {
2208 let s1: Step<i32, i32> = Step::Loop(1);
2209 let s2: Step<i32, i32> = Step::Loop(2);
2210 let s3: Step<i32, i32> = Step::Done(3);
2211
2212 assert_eq!(
2213 lift2::<StepDoneAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s2),
2214 Step::Loop(3)
2215 );
2216 assert_eq!(
2217 lift2::<StepDoneAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s3),
2218 Step::Done(3)
2219 );
2220 }
2221
2222 #[test]
2228 fn test_pointed_step_with_loop() {
2229 assert_eq!(pure::<StepLoopAppliedBrand<()>, _>(5), Step::Done(5));
2230 }
2231
2232 #[test]
2236 fn test_pointed_step_with_done() {
2237 assert_eq!(pure::<StepDoneAppliedBrand<()>, _>(5), Step::Loop(5));
2238 }
2239
2240 #[test]
2247 fn test_apply_step_with_loop() {
2248 let f =
2249 pure::<StepLoopAppliedBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2250 x * 2
2251 }));
2252 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2253 assert_eq!(apply::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(f, x), Step::Done(10));
2254
2255 let loop_step: Step<i32, _> = Step::Loop(1);
2256 let f_loop =
2257 pure::<StepLoopAppliedBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2258 x * 2
2259 }));
2260 assert_eq!(
2261 apply::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f_loop, loop_step),
2262 Step::Loop(1)
2263 );
2264 }
2265
2266 #[test]
2271 fn test_apply_step_with_done() {
2272 let f =
2273 pure::<StepDoneAppliedBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2274 x * 2
2275 }));
2276 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2277 assert_eq!(apply::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(f, x), Step::Loop(10));
2278
2279 let done_step: Step<_, i32> = Step::Done(1);
2280 let f_done =
2281 pure::<StepDoneAppliedBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2282 x * 2
2283 }));
2284 assert_eq!(
2285 apply::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f_done, done_step),
2286 Step::Done(1)
2287 );
2288 }
2289
2290 #[test]
2296 fn test_bind_step_with_loop() {
2297 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2298 assert_eq!(
2299 bind::<StepLoopAppliedBrand<()>, _, _>(x, |i| pure::<StepLoopAppliedBrand<()>, _>(
2300 i * 2
2301 )),
2302 Step::Done(10)
2303 );
2304
2305 let loop_step: Step<i32, i32> = Step::Loop(1);
2306 assert_eq!(
2307 bind::<StepLoopAppliedBrand<i32>, _, _>(loop_step, |i| pure::<
2308 StepLoopAppliedBrand<i32>,
2309 _,
2310 >(i * 2)),
2311 Step::Loop(1)
2312 );
2313 }
2314
2315 #[test]
2319 fn test_bind_step_with_done() {
2320 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2321 assert_eq!(
2322 bind::<StepDoneAppliedBrand<()>, _, _>(x, |i| pure::<StepDoneAppliedBrand<()>, _>(
2323 i * 2
2324 )),
2325 Step::Loop(10)
2326 );
2327
2328 let done_step: Step<i32, i32> = Step::Done(1);
2329 assert_eq!(
2330 bind::<StepDoneAppliedBrand<i32>, _, _>(done_step, |i| pure::<
2331 StepDoneAppliedBrand<i32>,
2332 _,
2333 >(i * 2)),
2334 Step::Done(1)
2335 );
2336 }
2337
2338 #[test]
2344 fn test_foldable_step_with_loop() {
2345 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2346 assert_eq!(
2347 fold_right::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|a, b| a + b, 10, x),
2348 15
2349 );
2350 assert_eq!(fold_left::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|b, a| b + a, 10, x), 15);
2351 assert_eq!(
2352 fold_map::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|a: i32| a.to_string(), x),
2353 "5"
2354 );
2355
2356 let loop_step: Step<i32, i32> = Step::Loop(1);
2357 assert_eq!(
2358 fold_right::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(|a, b| a + b, 10, loop_step),
2359 10
2360 );
2361 }
2362
2363 #[test]
2367 fn test_foldable_step_with_done() {
2368 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2369 assert_eq!(
2370 fold_right::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|a, b| a + b, 10, x),
2371 15
2372 );
2373 assert_eq!(fold_left::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|b, a| b + a, 10, x), 15);
2374 assert_eq!(
2375 fold_map::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|a: i32| a.to_string(), x),
2376 "5"
2377 );
2378
2379 let done_step: Step<i32, i32> = Step::Done(1);
2380 assert_eq!(
2381 fold_right::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(|a, b| a + b, 10, done_step),
2382 10
2383 );
2384 }
2385
2386 #[test]
2392 fn test_traversable_step_with_loop() {
2393 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2394 assert_eq!(
2395 traverse::<StepLoopAppliedBrand<()>, _, _, OptionBrand>(|a| Some(a * 2), x),
2396 Some(Step::Done(10))
2397 );
2398
2399 let loop_step: Step<i32, i32> = Step::Loop(1);
2400 assert_eq!(
2401 traverse::<StepLoopAppliedBrand<i32>, _, _, OptionBrand>(|a| Some(a * 2), loop_step),
2402 Some(Step::Loop(1))
2403 );
2404 }
2405
2406 #[test]
2410 fn test_traversable_step_with_done() {
2411 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2412 assert_eq!(
2413 traverse::<StepDoneAppliedBrand<()>, _, _, OptionBrand>(|a| Some(a * 2), x),
2414 Some(Step::Loop(10))
2415 );
2416
2417 let done_step: Step<i32, i32> = Step::Done(1);
2418 assert_eq!(
2419 traverse::<StepDoneAppliedBrand<i32>, _, _, OptionBrand>(|a| Some(a * 2), done_step),
2420 Some(Step::Done(1))
2421 );
2422 }
2423
2424 #[test]
2430 fn test_par_foldable_step_with_loop() {
2431 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2432 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|a: i32| a.to_string());
2433 assert_eq!(par_fold_map::<ArcFnBrand, StepLoopAppliedBrand<()>, _, _>(f, x), "5");
2434 }
2435
2436 #[test]
2440 fn test_par_foldable_step_with_done() {
2441 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2442 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|a: i32| a.to_string());
2443 assert_eq!(par_fold_map::<ArcFnBrand, StepDoneAppliedBrand<()>, _, _>(f, x), "5");
2444 }
2445
2446 #[quickcheck]
2450 fn monad_left_identity_step_with_loop(a: i32) -> bool {
2451 let f = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_mul(2));
2452 bind::<StepLoopAppliedBrand<i32>, _, _>(pure::<StepLoopAppliedBrand<i32>, _>(a), f) == f(a)
2453 }
2454
2455 #[quickcheck]
2457 fn monad_right_identity_step_with_loop(x: Step<i32, i32>) -> bool {
2458 bind::<StepLoopAppliedBrand<i32>, _, _>(x, pure::<StepLoopAppliedBrand<i32>, _>) == x
2459 }
2460
2461 #[quickcheck]
2463 fn monad_associativity_step_with_loop(x: Step<i32, i32>) -> bool {
2464 let f = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_mul(2));
2465 let g = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_add(1));
2466 bind::<StepLoopAppliedBrand<i32>, _, _>(bind::<StepLoopAppliedBrand<i32>, _, _>(x, f), g)
2467 == bind::<StepLoopAppliedBrand<i32>, _, _>(x, |a| {
2468 bind::<StepLoopAppliedBrand<i32>, _, _>(f(a), g)
2469 })
2470 }
2471
2472 #[quickcheck]
2476 fn monad_left_identity_step_with_done(a: i32) -> bool {
2477 let f = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_mul(2));
2478 bind::<StepDoneAppliedBrand<i32>, _, _>(pure::<StepDoneAppliedBrand<i32>, _>(a), f) == f(a)
2479 }
2480
2481 #[quickcheck]
2483 fn monad_right_identity_step_with_done(x: Step<i32, i32>) -> bool {
2484 bind::<StepDoneAppliedBrand<i32>, _, _>(x, pure::<StepDoneAppliedBrand<i32>, _>) == x
2485 }
2486
2487 #[quickcheck]
2489 fn monad_associativity_step_with_done(x: Step<i32, i32>) -> bool {
2490 let f = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_mul(2));
2491 let g = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_add(1));
2492 bind::<StepDoneAppliedBrand<i32>, _, _>(bind::<StepDoneAppliedBrand<i32>, _, _>(x, f), g)
2493 == bind::<StepDoneAppliedBrand<i32>, _, _>(x, |a| {
2494 bind::<StepDoneAppliedBrand<i32>, _, _>(f(a), g)
2495 })
2496 }
2497}