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 Pointed,
42 Semiapplicative,
43 Semimonad,
44 Traversable,
45 },
46 impl_kind,
47 kinds::*,
48 },
49 fp_macros::*,
50 };
51
52 #[document_type_parameters(
67 r#"The "loop" type - when we return `Loop(a)`, we continue with `a`."#,
68 r#"The "done" type - when we return `Done(b)`, we're finished."#
69 )]
70 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
77 pub enum Step<A, B> {
78 Loop(A),
80 Done(B),
82 }
83
84 #[document_type_parameters(
85 r#"The "loop" type - when we return `Loop(a)`, we continue with `a`."#,
86 r#"The "done" type - when we return `Done(b)`, we're finished."#
87 )]
88 #[document_parameters("The step value.")]
89 impl<A, B> Step<A, B> {
90 #[document_signature]
92 #[document_returns("`true` if the step is a loop, `false` otherwise.")]
94 #[inline]
96 #[document_examples]
97 pub fn is_loop(&self) -> bool {
105 matches!(self, Step::Loop(_))
106 }
107
108 #[document_signature]
110 #[document_returns("`true` if the step is done, `false` otherwise.")]
112 #[inline]
114 #[document_examples]
115 pub fn is_done(&self) -> bool {
123 matches!(self, Step::Done(_))
124 }
125
126 #[document_signature]
128 #[document_type_parameters("The new loop type.")]
130 #[document_parameters("The function to apply to the loop value.")]
132 #[document_returns("A new `Step` with the loop value transformed.")]
134 #[document_examples]
136 pub fn map_loop<C>(
145 self,
146 f: impl FnOnce(A) -> C,
147 ) -> Step<C, B> {
148 match self {
149 Step::Loop(a) => Step::Loop(f(a)),
150 Step::Done(b) => Step::Done(b),
151 }
152 }
153
154 #[document_signature]
156 #[document_type_parameters("The new done type.")]
158 #[document_parameters("The function to apply to the done value.")]
160 #[document_returns("A new `Step` with the done value transformed.")]
162 #[document_examples]
164 pub fn map_done<C>(
173 self,
174 f: impl FnOnce(B) -> C,
175 ) -> Step<A, C> {
176 match self {
177 Step::Loop(a) => Step::Loop(a),
178 Step::Done(b) => Step::Done(f(b)),
179 }
180 }
181
182 #[document_signature]
184 #[document_type_parameters("The new loop type.", "The new done type.")]
186 #[document_parameters(
188 "The function to apply to the loop value.",
189 "The function to apply to the done value."
190 )]
191 #[document_returns("A new `Step` with both values transformed.")]
193 #[document_examples]
194 pub fn bimap<C, D>(
203 self,
204 f: impl FnOnce(A) -> C,
205 g: impl FnOnce(B) -> D,
206 ) -> Step<C, D> {
207 match self {
208 Step::Loop(a) => Step::Loop(f(a)),
209 Step::Done(b) => Step::Done(g(b)),
210 }
211 }
212
213 #[document_signature]
217 #[document_type_parameters("The accumulator type.")]
219 #[document_parameters(
221 "The step function for the Loop variant.",
222 "The step function for the Done variant.",
223 "The initial accumulator."
224 )]
225 #[document_returns("The result of folding.")]
227 #[document_examples]
229 pub fn bi_fold_right<C>(
237 self,
238 f: impl FnOnce(A, C) -> C,
239 g: impl FnOnce(B, C) -> C,
240 z: C,
241 ) -> C {
242 match self {
243 Step::Loop(a) => f(a, z),
244 Step::Done(b) => g(b, z),
245 }
246 }
247
248 #[document_signature]
252 #[document_type_parameters("The accumulator type.")]
254 #[document_parameters(
256 "The step function for the Loop variant.",
257 "The step function for the Done variant.",
258 "The initial accumulator."
259 )]
260 #[document_returns("The result of folding.")]
262 #[document_examples]
264 pub fn bi_fold_left<C>(
272 self,
273 f: impl FnOnce(C, A) -> C,
274 g: impl FnOnce(C, B) -> C,
275 z: C,
276 ) -> C {
277 match self {
278 Step::Loop(a) => f(z, a),
279 Step::Done(b) => g(z, b),
280 }
281 }
282
283 #[document_signature]
287 #[document_type_parameters("The monoid type.")]
289 #[document_parameters(
291 "The function mapping the Loop value to the monoid.",
292 "The function mapping the Done value to the monoid."
293 )]
294 #[document_returns("The monoid value.")]
296 #[document_examples]
298 pub fn bi_fold_map<M>(
306 self,
307 f: impl FnOnce(A) -> M,
308 g: impl FnOnce(B) -> M,
309 ) -> M {
310 match self {
311 Step::Loop(a) => f(a),
312 Step::Done(b) => g(b),
313 }
314 }
315
316 #[document_signature]
321 #[document_type_parameters("The accumulator type.")]
323 #[document_parameters(
325 "The function to apply to the Done value and the accumulator.",
326 "The initial accumulator."
327 )]
328 #[document_returns("The result of folding.")]
330 #[document_examples]
332 pub fn fold_right<C>(
340 self,
341 f: impl FnOnce(B, C) -> C,
342 initial: C,
343 ) -> C {
344 match self {
345 Step::Loop(_) => initial,
346 Step::Done(b) => f(b, initial),
347 }
348 }
349
350 #[document_signature]
355 #[document_type_parameters("The accumulator type.")]
357 #[document_parameters(
359 "The function to apply to the accumulator and the Done value.",
360 "The initial accumulator."
361 )]
362 #[document_returns("The result of folding.")]
364 #[document_examples]
366 pub fn fold_left<C>(
374 self,
375 f: impl FnOnce(C, B) -> C,
376 initial: C,
377 ) -> C {
378 match self {
379 Step::Loop(_) => initial,
380 Step::Done(b) => f(initial, b),
381 }
382 }
383
384 #[document_signature]
389 #[document_type_parameters("The monoid type.")]
391 #[document_parameters("The mapping function.")]
393 #[document_returns("The monoid value.")]
395 #[document_examples]
397 pub fn fold_map<M: Monoid>(
405 self,
406 f: impl FnOnce(B) -> M,
407 ) -> M {
408 match self {
409 Step::Loop(_) => M::empty(),
410 Step::Done(b) => f(b),
411 }
412 }
413
414 #[document_signature]
419 #[document_type_parameters("The type of the resulting Done value.")]
421 #[document_parameters("The function to apply to the Done value.")]
423 #[document_returns("The result of the computation.")]
425 #[document_examples]
427 pub fn bind<C>(
436 self,
437 f: impl FnOnce(B) -> Step<A, C>,
438 ) -> Step<A, C> {
439 match self {
440 Step::Loop(a) => Step::Loop(a),
441 Step::Done(b) => f(b),
442 }
443 }
444
445 #[document_signature]
450 #[document_type_parameters("The type of the resulting Loop value.")]
452 #[document_parameters("The function to apply to the Loop value.")]
454 #[document_returns("The result of the computation.")]
456 #[document_examples]
458 pub fn bind_loop<C>(
467 self,
468 f: impl FnOnce(A) -> Step<C, B>,
469 ) -> Step<C, B> {
470 match self {
471 Step::Loop(a) => f(a),
472 Step::Done(b) => Step::Done(b),
473 }
474 }
475 }
476
477 #[document_type_parameters(
478 "The lifetime of the values.",
479 "The type of the Loop value.",
480 "The type of the Done value."
481 )]
482 #[document_parameters("The step instance.")]
483 impl<'a, A: 'a, B: 'a> Step<A, B> {
484 #[document_signature]
488 #[document_type_parameters(
490 "The output type for the Loop value.",
491 "The output type for the Done value.",
492 "The applicative context."
493 )]
494 #[document_parameters(
496 "The function for the Loop value.",
497 "The function for the Done value."
498 )]
499 #[document_returns("The transformed step wrapped in the applicative context.")]
501 #[document_examples]
503 pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
515 self,
516 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
517 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
518 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Step<C, D>>)
519 where
520 Step<C, D>: Clone, {
521 match self {
522 Step::Loop(a) => F::map(|c| Step::Loop(c), f(a)),
523 Step::Done(b) => F::map(|d| Step::Done(d), g(b)),
524 }
525 }
526 }
527
528 impl_kind! {
529 for StepBrand {
530 type Of<A, B> = Step<A, B>;
531 }
532 }
533
534 impl_kind! {
535 for StepBrand {
536 type Of<'a, A: 'a, B: 'a>: 'a = Step<A, B>;
537 }
538 }
539
540 impl Bifunctor for StepBrand {
541 #[document_signature]
545 #[document_type_parameters(
547 "The lifetime of the values.",
548 "The type of the loop value.",
549 "The type of the mapped loop value.",
550 "The type of the done value.",
551 "The type of the mapped done value."
552 )]
553 #[document_parameters(
555 "The function to apply to the loop value.",
556 "The function to apply to the done value.",
557 "The step to map over."
558 )]
559 #[document_returns("A new step containing the mapped values.")]
561 #[document_examples]
562 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
575 f: impl Fn(A) -> B + 'a,
576 g: impl Fn(C) -> D + 'a,
577 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
578 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
579 p.bimap(f, g)
580 }
581 }
582
583 impl Bifoldable for StepBrand {
584 #[document_signature]
588 #[document_type_parameters(
590 "The lifetime of the values.",
591 "The brand of the cloneable function to use.",
592 "The type of the Loop value.",
593 "The type of the Done value.",
594 "The accumulator type."
595 )]
596 #[document_parameters(
598 "The step function for the Loop variant.",
599 "The step function for the Done variant.",
600 "The initial accumulator.",
601 "The step to fold."
602 )]
603 #[document_returns("The folded result.")]
605 #[document_examples]
606 fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
621 f: impl Fn(A, C) -> C + 'a,
622 g: impl Fn(B, C) -> C + 'a,
623 z: C,
624 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
625 ) -> C {
626 p.bi_fold_right(f, g, z)
627 }
628
629 #[document_signature]
633 #[document_type_parameters(
635 "The lifetime of the values.",
636 "The brand of the cloneable function to use.",
637 "The type of the Loop value.",
638 "The type of the Done value.",
639 "The accumulator type."
640 )]
641 #[document_parameters(
643 "The step function for the Loop variant.",
644 "The step function for the Done variant.",
645 "The initial accumulator.",
646 "The step to fold."
647 )]
648 #[document_returns("The folded result.")]
650 #[document_examples]
651 fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
666 f: impl Fn(C, A) -> C + 'a,
667 g: impl Fn(C, B) -> C + 'a,
668 z: C,
669 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
670 ) -> C {
671 p.bi_fold_left(f, g, z)
672 }
673
674 #[document_signature]
678 #[document_type_parameters(
680 "The lifetime of the values.",
681 "The brand of the cloneable function to use.",
682 "The type of the Loop value.",
683 "The type of the Done value.",
684 "The monoid type."
685 )]
686 #[document_parameters(
688 "The function mapping the Loop value to the monoid.",
689 "The function mapping the Done value to the monoid.",
690 "The step to fold."
691 )]
692 #[document_returns("The monoid value.")]
694 #[document_examples]
695 fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
714 f: impl Fn(A) -> M + 'a,
715 g: impl Fn(B) -> M + 'a,
716 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
717 ) -> M
718 where
719 M: Monoid + 'a, {
720 p.bi_fold_map(f, g)
721 }
722 }
723
724 impl Bitraversable for StepBrand {
725 #[document_signature]
730 #[document_type_parameters(
732 "The lifetime of the values.",
733 "The type of the Loop value.",
734 "The type of the Done value.",
735 "The output type for Loop.",
736 "The output type for Done.",
737 "The applicative context."
738 )]
739 #[document_parameters(
741 "The function applied to the Loop value.",
742 "The function applied to the Done value.",
743 "The step to traverse."
744 )]
745 #[document_returns("The transformed step wrapped in the applicative context.")]
747 #[document_examples]
748 fn bi_traverse<
767 'a,
768 A: 'a + Clone,
769 B: 'a + Clone,
770 C: 'a + Clone,
771 D: 'a + Clone,
772 F: Applicative,
773 >(
774 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
775 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
776 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
777 ) -> 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>)>)
778 {
779 p.bi_traverse::<C, D, F>(f, g)
780 }
781 }
782
783 impl_kind! {
786 impl<LoopType: 'static> for StepLoopAppliedBrand<LoopType> {
787 type Of<'a, B: 'a>: 'a = Step<LoopType, B>;
788 }
789 }
790
791 #[document_type_parameters("The loop type.")]
792 impl<LoopType: 'static> Functor for StepLoopAppliedBrand<LoopType> {
793 #[document_signature]
797 #[document_type_parameters(
799 "The lifetime of the values.",
800 "The type of the done value.",
801 "The type of the result of applying the function."
802 )]
803 #[document_parameters("The function to apply to the done value.", "The step to map over.")]
805 #[document_returns(
807 "A new step containing the result of applying the function to the done value."
808 )]
809 #[document_examples]
811 fn map<'a, A: 'a, B: 'a>(
825 func: impl Fn(A) -> B + 'a,
826 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
827 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
828 fa.map_done(func)
829 }
830 }
831
832 #[document_type_parameters("The loop type.")]
833 impl<LoopType: Clone + 'static> Lift for StepLoopAppliedBrand<LoopType> {
834 #[document_signature]
838 #[document_type_parameters(
840 "The lifetime of the values.",
841 "The type of the first value.",
842 "The type of the second value.",
843 "The type of the result."
844 )]
845 #[document_parameters(
847 "The binary function to apply.",
848 "The first step.",
849 "The second step."
850 )]
851 #[document_returns(
853 "`Done(f(a, b))` if both steps are `Done`, otherwise the first loop encountered."
854 )]
855 #[document_examples]
856 fn lift2<'a, A, B, C>(
882 func: impl Fn(A, B) -> C + 'a,
883 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
884 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
885 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
886 where
887 A: Clone + 'a,
888 B: Clone + 'a,
889 C: 'a, {
890 match (fa, fb) {
891 (Step::Done(a), Step::Done(b)) => Step::Done(func(a, b)),
892 (Step::Loop(e), _) => Step::Loop(e),
893 (_, Step::Loop(e)) => Step::Loop(e),
894 }
895 }
896 }
897
898 #[document_type_parameters("The loop type.")]
899 impl<LoopType: 'static> Pointed for StepLoopAppliedBrand<LoopType> {
900 #[document_signature]
904 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
906 #[document_parameters("The value to wrap.")]
908 #[document_returns("`Done(a)`.")]
910 #[document_examples]
912 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
923 Step::Done(a)
924 }
925 }
926
927 #[document_type_parameters("The loop type.")]
928 impl<LoopType: Clone + 'static> ApplyFirst for StepLoopAppliedBrand<LoopType> {}
929
930 #[document_type_parameters("The loop type.")]
931 impl<LoopType: Clone + 'static> ApplySecond for StepLoopAppliedBrand<LoopType> {}
932
933 #[document_type_parameters("The loop type.")]
934 impl<LoopType: Clone + 'static> Semiapplicative for StepLoopAppliedBrand<LoopType> {
935 #[document_signature]
939 #[document_type_parameters(
941 "The lifetime of the values.",
942 "The brand of the cloneable function wrapper.",
943 "The type of the input value.",
944 "The type of the output value."
945 )]
946 #[document_parameters(
948 "The step containing the function.",
949 "The step containing the value."
950 )]
951 #[document_returns(
953 "`Done(f(a))` if both are `Done`, otherwise the first loop encountered."
954 )]
955 #[document_examples]
956 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
972 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
973 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
974 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
975 match (ff, fa) {
976 (Step::Done(f), Step::Done(a)) => Step::Done(f(a)),
977 (Step::Loop(e), _) => Step::Loop(e),
978 (_, Step::Loop(e)) => Step::Loop(e),
979 }
980 }
981 }
982
983 #[document_type_parameters("The loop type.")]
984 impl<LoopType: Clone + 'static> Semimonad for StepLoopAppliedBrand<LoopType> {
985 #[document_signature]
989 #[document_type_parameters(
991 "The lifetime of the values.",
992 "The type of the result of the first computation.",
993 "The type of the result of the second computation."
994 )]
995 #[document_parameters(
997 "The first step.",
998 "The function to apply to the value inside the step."
999 )]
1000 #[document_returns(
1002 "The result of applying `f` to the value if `ma` is `Done`, otherwise the original loop."
1003 )]
1004 #[document_examples]
1005 fn bind<'a, A: 'a, B: 'a>(
1019 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1020 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1021 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1022 ma.bind(func)
1023 }
1024 }
1025
1026 #[document_type_parameters("The loop type.")]
1027 impl<LoopType: 'static> Foldable for StepLoopAppliedBrand<LoopType> {
1028 #[document_signature]
1032 #[document_type_parameters(
1034 "The lifetime of the values.",
1035 "The brand of the cloneable function to use.",
1036 "The type of the elements in the structure.",
1037 "The type of the accumulator."
1038 )]
1039 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1041 #[document_returns("`func(a, initial)` if `fa` is `Done(a)`, otherwise `initial`.")]
1043 #[document_examples]
1045 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1067 func: impl Fn(A, B) -> B + 'a,
1068 initial: B,
1069 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1070 ) -> B
1071 where
1072 FnBrand: CloneableFn + 'a, {
1073 fa.fold_right(func, initial)
1074 }
1075
1076 #[document_signature]
1080 #[document_type_parameters(
1082 "The lifetime of the values.",
1083 "The brand of the cloneable function to use.",
1084 "The type of the elements in the structure.",
1085 "The type of the accumulator."
1086 )]
1087 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1089 #[document_returns("`func(initial, a)` if `fa` is `Done(a)`, otherwise `initial`.")]
1091 #[document_examples]
1093 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1115 func: impl Fn(B, A) -> B + 'a,
1116 initial: B,
1117 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1118 ) -> B
1119 where
1120 FnBrand: CloneableFn + 'a, {
1121 fa.fold_left(func, initial)
1122 }
1123
1124 #[document_signature]
1128 #[document_type_parameters(
1130 "The lifetime of the values.",
1131 "The brand of the cloneable function to use.",
1132 "The type of the elements in the structure.",
1133 "The type of the monoid."
1134 )]
1135 #[document_parameters("The mapping function.", "The step to fold.")]
1137 #[document_returns("`func(a)` if `fa` is `Done(a)`, otherwise `M::empty()`.")]
1139 #[document_examples]
1141 fn fold_map<'a, FnBrand, A: 'a, M>(
1165 func: impl Fn(A) -> M + 'a,
1166 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1167 ) -> M
1168 where
1169 M: Monoid + 'a,
1170 FnBrand: CloneableFn + 'a, {
1171 fa.fold_map(func)
1172 }
1173 }
1174
1175 #[document_type_parameters("The loop type.")]
1176 impl<LoopType: Clone + 'static> Traversable for StepLoopAppliedBrand<LoopType> {
1177 #[document_signature]
1181 #[document_type_parameters(
1183 "The lifetime of the values.",
1184 "The type of the elements in the traversable structure.",
1185 "The type of the elements in the resulting traversable structure.",
1186 "The applicative context."
1187 )]
1188 #[document_parameters("The function to apply.", "The step to traverse.")]
1190 #[document_returns("The step wrapped in the applicative context.")]
1192 #[document_examples]
1194 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1215 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1216 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1217 ) -> 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>)>)
1218 where
1219 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1220 match ta {
1221 Step::Done(a) => F::map(|b| Step::Done(b), func(a)),
1222 Step::Loop(e) => F::pure(Step::Loop(e)),
1223 }
1224 }
1225
1226 #[document_signature]
1230 #[document_type_parameters(
1232 "The lifetime of the values.",
1233 "The type of the elements in the traversable structure.",
1234 "The applicative context."
1235 )]
1236 #[document_parameters("The step containing the applicative value.")]
1238 #[document_returns("The step wrapped in the applicative context.")]
1240 #[document_examples]
1242 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1260 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>)>)
1261 ) -> 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>)>)
1262 where
1263 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1264 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1265 match ta {
1266 Step::Done(fa) => F::map(|a| Step::Done(a), fa),
1267 Step::Loop(e) => F::pure(Step::Loop(e)),
1268 }
1269 }
1270 }
1271
1272 impl_kind! {
1275 impl<DoneType: 'static> for StepDoneAppliedBrand<DoneType> {
1276 type Of<'a, A: 'a>: 'a = Step<A, DoneType>;
1277 }
1278 }
1279
1280 #[document_type_parameters("The done type.")]
1281 impl<DoneType: 'static> Functor for StepDoneAppliedBrand<DoneType> {
1282 #[document_signature]
1286 #[document_type_parameters(
1288 "The lifetime of the values.",
1289 "The type of the loop value.",
1290 "The type of the result of applying the function."
1291 )]
1292 #[document_parameters("The function to apply to the loop value.", "The step to map over.")]
1294 #[document_returns(
1296 "A new step containing the result of applying the function to the loop value."
1297 )]
1298 #[document_examples]
1300 fn map<'a, A: 'a, B: 'a>(
1314 func: impl Fn(A) -> B + 'a,
1315 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1316 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1317 fa.map_loop(func)
1318 }
1319 }
1320
1321 #[document_type_parameters("The done type.")]
1322 impl<DoneType: Clone + 'static> Lift for StepDoneAppliedBrand<DoneType> {
1323 #[document_signature]
1327 #[document_type_parameters(
1329 "The lifetime of the values.",
1330 "The type of the first loop value.",
1331 "The type of the second loop value.",
1332 "The type of the result loop value."
1333 )]
1334 #[document_parameters(
1336 "The binary function to apply to the loops.",
1337 "The first step.",
1338 "The second step."
1339 )]
1340 #[document_returns(
1342 "`Loop(f(a, b))` if both steps are `Loop`, otherwise the first done encountered."
1343 )]
1344 #[document_examples]
1345 fn lift2<'a, A, B, C>(
1371 func: impl Fn(A, B) -> C + 'a,
1372 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1373 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1374 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1375 where
1376 A: Clone + 'a,
1377 B: Clone + 'a,
1378 C: 'a, {
1379 match (fa, fb) {
1380 (Step::Loop(a), Step::Loop(b)) => Step::Loop(func(a, b)),
1381 (Step::Done(t), _) => Step::Done(t),
1382 (_, Step::Done(t)) => Step::Done(t),
1383 }
1384 }
1385 }
1386
1387 #[document_type_parameters("The done type.")]
1388 impl<DoneType: 'static> Pointed for StepDoneAppliedBrand<DoneType> {
1389 #[document_signature]
1393 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1395 #[document_parameters("The value to wrap.")]
1397 #[document_returns("`Loop(a)`.")]
1399 #[document_examples]
1401 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1412 Step::Loop(a)
1413 }
1414 }
1415
1416 #[document_type_parameters("The done type.")]
1417 impl<DoneType: Clone + 'static> ApplyFirst for StepDoneAppliedBrand<DoneType> {}
1418
1419 #[document_type_parameters("The done type.")]
1420 impl<DoneType: Clone + 'static> ApplySecond for StepDoneAppliedBrand<DoneType> {}
1421
1422 #[document_type_parameters("The done type.")]
1423 impl<DoneType: Clone + 'static> Semiapplicative for StepDoneAppliedBrand<DoneType> {
1424 #[document_signature]
1428 #[document_type_parameters(
1430 "The lifetime of the values.",
1431 "The brand of the cloneable function wrapper.",
1432 "The type of the input value.",
1433 "The type of the output value."
1434 )]
1435 #[document_parameters(
1437 "The step containing the function (in Loop).",
1438 "The step containing the value (in Loop)."
1439 )]
1440 #[document_returns(
1442 "`Loop(f(a))` if both are `Loop`, otherwise the first done encountered."
1443 )]
1444 #[document_examples]
1445 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1461 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1462 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1463 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1464 match (ff, fa) {
1465 (Step::Loop(f), Step::Loop(a)) => Step::Loop(f(a)),
1466 (Step::Done(t), _) => Step::Done(t),
1467 (_, Step::Done(t)) => Step::Done(t),
1468 }
1469 }
1470 }
1471
1472 #[document_type_parameters("The done type.")]
1473 impl<DoneType: Clone + 'static> Semimonad for StepDoneAppliedBrand<DoneType> {
1474 #[document_signature]
1478 #[document_type_parameters(
1480 "The lifetime of the values.",
1481 "The type of the result of the first computation.",
1482 "The type of the result of the second computation."
1483 )]
1484 #[document_parameters("The first step.", "The function to apply to the loop value.")]
1486 #[document_returns(
1488 "The result of applying `f` to the loop if `ma` is `Loop`, otherwise the original done."
1489 )]
1490 #[document_examples]
1492 fn bind<'a, A: 'a, B: 'a>(
1506 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1507 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1508 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1509 ma.bind_loop(func)
1510 }
1511 }
1512
1513 #[document_type_parameters("The done type.")]
1514 impl<DoneType: 'static> Foldable for StepDoneAppliedBrand<DoneType> {
1515 #[document_signature]
1519 #[document_type_parameters(
1521 "The lifetime of the values.",
1522 "The brand of the cloneable function to use.",
1523 "The type of the elements in the structure.",
1524 "The type of the accumulator."
1525 )]
1526 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1528 #[document_returns("`func(a, initial)` if `fa` is `Loop(a)`, otherwise `initial`.")]
1530 #[document_examples]
1532 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1558 func: impl Fn(A, B) -> B + 'a,
1559 initial: B,
1560 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1561 ) -> B
1562 where
1563 FnBrand: CloneableFn + 'a, {
1564 match fa {
1565 Step::Loop(e) => func(e, initial),
1566 Step::Done(_) => initial,
1567 }
1568 }
1569
1570 #[document_signature]
1574 #[document_type_parameters(
1576 "The lifetime of the values.",
1577 "The brand of the cloneable function to use.",
1578 "The type of the elements in the structure.",
1579 "The type of the accumulator."
1580 )]
1581 #[document_parameters("The folding function.", "The initial value.", "The step to fold.")]
1583 #[document_returns("`func(initial, a)` if `fa` is `Loop(a)`, otherwise `initial`.")]
1585 #[document_examples]
1587 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1613 func: impl Fn(B, A) -> B + 'a,
1614 initial: B,
1615 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1616 ) -> B
1617 where
1618 FnBrand: CloneableFn + 'a, {
1619 match fa {
1620 Step::Loop(e) => func(initial, e),
1621 Step::Done(_) => initial,
1622 }
1623 }
1624
1625 #[document_signature]
1629 #[document_type_parameters(
1631 "The lifetime of the values.",
1632 "The brand of the cloneable function to use.",
1633 "The type of the elements in the structure.",
1634 "The type of the monoid."
1635 )]
1636 #[document_parameters("The mapping function.", "The step to fold.")]
1638 #[document_returns("`func(a)` if `fa` is `Loop(a)`, otherwise `M::empty()`.")]
1640 #[document_examples]
1642 fn fold_map<'a, FnBrand, A: 'a, M>(
1666 func: impl Fn(A) -> M + 'a,
1667 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1668 ) -> M
1669 where
1670 M: Monoid + 'a,
1671 FnBrand: CloneableFn + 'a, {
1672 match fa {
1673 Step::Loop(e) => func(e),
1674 Step::Done(_) => M::empty(),
1675 }
1676 }
1677 }
1678
1679 #[document_type_parameters("The done type.")]
1680 impl<DoneType: Clone + 'static> Traversable for StepDoneAppliedBrand<DoneType> {
1681 #[document_signature]
1685 #[document_type_parameters(
1687 "The lifetime of the values.",
1688 "The type of the elements in the traversable structure.",
1689 "The type of the elements in the resulting traversable structure.",
1690 "The applicative context."
1691 )]
1692 #[document_parameters("The function to apply.", "The step to traverse.")]
1694 #[document_returns("The step wrapped in the applicative context.")]
1696 #[document_examples]
1698 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1719 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1720 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1721 ) -> 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>)>)
1722 where
1723 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1724 match ta {
1725 Step::Loop(e) => F::map(|b| Step::Loop(b), func(e)),
1726 Step::Done(t) => F::pure(Step::Done(t)),
1727 }
1728 }
1729
1730 #[document_signature]
1734 #[document_type_parameters(
1736 "The lifetime of the values.",
1737 "The type of the elements in the traversable structure.",
1738 "The applicative context."
1739 )]
1740 #[document_parameters("The step containing the applicative value.")]
1742 #[document_returns("The step wrapped in the applicative context.")]
1744 #[document_examples]
1746 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1764 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>)>)
1765 ) -> 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>)>)
1766 where
1767 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1768 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1769 match ta {
1770 Step::Loop(fe) => F::map(|e| Step::Loop(e), fe),
1771 Step::Done(t) => F::pure(Step::Done(t)),
1772 }
1773 }
1774 }
1775}
1776pub use inner::*;
1777
1778#[cfg(test)]
1779mod tests {
1780 use {
1781 super::*,
1782 crate::{
1783 brands::*,
1784 classes::{
1785 bifunctor::*,
1786 foldable::*,
1787 functor::*,
1788 lift::*,
1789 pointed::*,
1790 semiapplicative::*,
1791 semimonad::*,
1792 traversable::*,
1793 },
1794 functions::*,
1795 },
1796 quickcheck::{
1797 Arbitrary,
1798 Gen,
1799 },
1800 quickcheck_macros::quickcheck,
1801 };
1802
1803 impl<A: Arbitrary, B: Arbitrary> Arbitrary for Step<A, B> {
1804 fn arbitrary(g: &mut Gen) -> Self {
1805 if bool::arbitrary(g) {
1806 Step::Loop(A::arbitrary(g))
1807 } else {
1808 Step::Done(B::arbitrary(g))
1809 }
1810 }
1811 }
1812
1813 #[test]
1817 fn test_is_loop() {
1818 let step: Step<i32, i32> = Step::Loop(1);
1819 assert!(step.is_loop());
1820 assert!(!step.is_done());
1821 }
1822
1823 #[test]
1827 fn test_is_done() {
1828 let step: Step<i32, i32> = Step::Done(1);
1829 assert!(step.is_done());
1830 assert!(!step.is_loop());
1831 }
1832
1833 #[test]
1837 fn test_map_loop() {
1838 let step: Step<i32, i32> = Step::Loop(1);
1839 let mapped = step.map_loop(|x| x + 1);
1840 assert_eq!(mapped, Step::Loop(2));
1841
1842 let done: Step<i32, i32> = Step::Done(1);
1843 let mapped_done = done.map_loop(|x| x + 1);
1844 assert_eq!(mapped_done, Step::Done(1));
1845 }
1846
1847 #[test]
1851 fn test_map_done() {
1852 let step: Step<i32, i32> = Step::Done(1);
1853 let mapped = step.map_done(|x| x + 1);
1854 assert_eq!(mapped, Step::Done(2));
1855
1856 let loop_step: Step<i32, i32> = Step::Loop(1);
1857 let mapped_loop = loop_step.map_done(|x| x + 1);
1858 assert_eq!(mapped_loop, Step::Loop(1));
1859 }
1860
1861 #[test]
1865 fn test_bimap() {
1866 let step: Step<i32, i32> = Step::Loop(1);
1867 let mapped = step.bimap(|x| x + 1, |x| x * 2);
1868 assert_eq!(mapped, Step::Loop(2));
1869
1870 let done: Step<i32, i32> = Step::Done(1);
1871 let mapped_done = done.bimap(|x| x + 1, |x| x * 2);
1872 assert_eq!(mapped_done, Step::Done(2));
1873 }
1874
1875 #[test]
1877 fn test_functor_step_with_loop() {
1878 let step: Step<i32, i32> = Step::Done(5);
1879 assert_eq!(map::<StepLoopAppliedBrand<_>, _, _>(|x: i32| x * 2, step), Step::Done(10));
1880
1881 let loop_step: Step<i32, i32> = Step::Loop(5);
1882 assert_eq!(map::<StepLoopAppliedBrand<_>, _, _>(|x: i32| x * 2, loop_step), Step::Loop(5));
1883 }
1884
1885 #[test]
1887 fn test_functor_step_with_done() {
1888 let step: Step<i32, i32> = Step::Loop(5);
1889 assert_eq!(map::<StepDoneAppliedBrand<_>, _, _>(|x: i32| x * 2, step), Step::Loop(10));
1890
1891 let done_step: Step<i32, i32> = Step::Done(5);
1892 assert_eq!(map::<StepDoneAppliedBrand<_>, _, _>(|x: i32| x * 2, done_step), Step::Done(5));
1893 }
1894
1895 #[test]
1897 fn test_bifunctor_step() {
1898 let step: Step<i32, i32> = Step::Loop(5);
1899 assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b| b * 2, step), Step::Loop(6));
1900
1901 let done: Step<i32, i32> = Step::Done(5);
1902 assert_eq!(bimap::<StepBrand, _, _, _, _>(|a| a + 1, |b| b * 2, done), Step::Done(10));
1903 }
1904
1905 #[quickcheck]
1908 fn functor_identity_step_with_loop(x: Step<i32, i32>) -> bool {
1909 map::<StepLoopAppliedBrand<i32>, _, _>(identity, x) == x
1910 }
1911
1912 #[quickcheck]
1913 fn functor_composition_step_with_loop(x: Step<i32, i32>) -> bool {
1914 let f = |x: i32| x.wrapping_add(1);
1915 let g = |x: i32| x.wrapping_mul(2);
1916 map::<StepLoopAppliedBrand<i32>, _, _>(compose(f, g), x)
1917 == map::<StepLoopAppliedBrand<i32>, _, _>(
1918 f,
1919 map::<StepLoopAppliedBrand<i32>, _, _>(g, x),
1920 )
1921 }
1922
1923 #[quickcheck]
1926 fn functor_identity_step_with_done(x: Step<i32, i32>) -> bool {
1927 map::<StepDoneAppliedBrand<i32>, _, _>(identity, x) == x
1928 }
1929
1930 #[quickcheck]
1931 fn functor_composition_step_with_done(x: Step<i32, i32>) -> bool {
1932 let f = |x: i32| x.wrapping_add(1);
1933 let g = |x: i32| x.wrapping_mul(2);
1934 map::<StepDoneAppliedBrand<i32>, _, _>(compose(f, g), x)
1935 == map::<StepDoneAppliedBrand<i32>, _, _>(
1936 f,
1937 map::<StepDoneAppliedBrand<i32>, _, _>(g, x),
1938 )
1939 }
1940
1941 #[quickcheck]
1944 fn bifunctor_identity_step(x: Step<i32, i32>) -> bool {
1945 bimap::<StepBrand, _, _, _, _>(identity, identity, x) == x
1946 }
1947
1948 #[quickcheck]
1949 fn bifunctor_composition_step(x: Step<i32, i32>) -> bool {
1950 let f = |x: i32| x.wrapping_add(1);
1951 let g = |x: i32| x.wrapping_mul(2);
1952 let h = |x: i32| x.wrapping_sub(1);
1953 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1954
1955 bimap::<StepBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1956 == bimap::<StepBrand, _, _, _, _>(f, h, bimap::<StepBrand, _, _, _, _>(g, i, x))
1957 }
1958
1959 #[test]
1966 fn test_lift2_step_with_loop() {
1967 let s1: Step<i32, i32> = Step::Done(1);
1968 let s2: Step<i32, i32> = Step::Done(2);
1969 let s3: Step<i32, i32> = Step::Loop(3);
1970
1971 assert_eq!(
1972 lift2::<StepLoopAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s2),
1973 Step::Done(3)
1974 );
1975 assert_eq!(
1976 lift2::<StepLoopAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s3),
1977 Step::Loop(3)
1978 );
1979 }
1980
1981 #[test]
1986 fn test_lift2_step_with_done() {
1987 let s1: Step<i32, i32> = Step::Loop(1);
1988 let s2: Step<i32, i32> = Step::Loop(2);
1989 let s3: Step<i32, i32> = Step::Done(3);
1990
1991 assert_eq!(
1992 lift2::<StepDoneAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s2),
1993 Step::Loop(3)
1994 );
1995 assert_eq!(
1996 lift2::<StepDoneAppliedBrand<i32>, _, _, _>(|x, y| x + y, s1, s3),
1997 Step::Done(3)
1998 );
1999 }
2000
2001 #[test]
2007 fn test_pointed_step_with_loop() {
2008 assert_eq!(pure::<StepLoopAppliedBrand<()>, _>(5), Step::Done(5));
2009 }
2010
2011 #[test]
2015 fn test_pointed_step_with_done() {
2016 assert_eq!(pure::<StepDoneAppliedBrand<()>, _>(5), Step::Loop(5));
2017 }
2018
2019 #[test]
2026 fn test_apply_step_with_loop() {
2027 let f =
2028 pure::<StepLoopAppliedBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2029 x * 2
2030 }));
2031 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2032 assert_eq!(apply::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(f, x), Step::Done(10));
2033
2034 let loop_step: Step<i32, _> = Step::Loop(1);
2035 let f_loop =
2036 pure::<StepLoopAppliedBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2037 x * 2
2038 }));
2039 assert_eq!(
2040 apply::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(f_loop, loop_step),
2041 Step::Loop(1)
2042 );
2043 }
2044
2045 #[test]
2050 fn test_apply_step_with_done() {
2051 let f =
2052 pure::<StepDoneAppliedBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2053 x * 2
2054 }));
2055 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2056 assert_eq!(apply::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(f, x), Step::Loop(10));
2057
2058 let done_step: Step<_, i32> = Step::Done(1);
2059 let f_done =
2060 pure::<StepDoneAppliedBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| {
2061 x * 2
2062 }));
2063 assert_eq!(
2064 apply::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(f_done, done_step),
2065 Step::Done(1)
2066 );
2067 }
2068
2069 #[test]
2075 fn test_bind_step_with_loop() {
2076 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2077 assert_eq!(
2078 bind::<StepLoopAppliedBrand<()>, _, _>(x, |i| pure::<StepLoopAppliedBrand<()>, _>(
2079 i * 2
2080 )),
2081 Step::Done(10)
2082 );
2083
2084 let loop_step: Step<i32, i32> = Step::Loop(1);
2085 assert_eq!(
2086 bind::<StepLoopAppliedBrand<i32>, _, _>(loop_step, |i| pure::<
2087 StepLoopAppliedBrand<i32>,
2088 _,
2089 >(i * 2)),
2090 Step::Loop(1)
2091 );
2092 }
2093
2094 #[test]
2098 fn test_bind_step_with_done() {
2099 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2100 assert_eq!(
2101 bind::<StepDoneAppliedBrand<()>, _, _>(x, |i| pure::<StepDoneAppliedBrand<()>, _>(
2102 i * 2
2103 )),
2104 Step::Loop(10)
2105 );
2106
2107 let done_step: Step<i32, i32> = Step::Done(1);
2108 assert_eq!(
2109 bind::<StepDoneAppliedBrand<i32>, _, _>(done_step, |i| pure::<
2110 StepDoneAppliedBrand<i32>,
2111 _,
2112 >(i * 2)),
2113 Step::Done(1)
2114 );
2115 }
2116
2117 #[test]
2123 fn test_foldable_step_with_loop() {
2124 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2125 assert_eq!(
2126 fold_right::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|a, b| a + b, 10, x),
2127 15
2128 );
2129 assert_eq!(fold_left::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|b, a| b + a, 10, x), 15);
2130 assert_eq!(
2131 fold_map::<RcFnBrand, StepLoopAppliedBrand<()>, _, _>(|a: i32| a.to_string(), x),
2132 "5"
2133 );
2134
2135 let loop_step: Step<i32, i32> = Step::Loop(1);
2136 assert_eq!(
2137 fold_right::<RcFnBrand, StepLoopAppliedBrand<i32>, _, _>(|a, b| a + b, 10, loop_step),
2138 10
2139 );
2140 }
2141
2142 #[test]
2146 fn test_foldable_step_with_done() {
2147 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2148 assert_eq!(
2149 fold_right::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|a, b| a + b, 10, x),
2150 15
2151 );
2152 assert_eq!(fold_left::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|b, a| b + a, 10, x), 15);
2153 assert_eq!(
2154 fold_map::<RcFnBrand, StepDoneAppliedBrand<()>, _, _>(|a: i32| a.to_string(), x),
2155 "5"
2156 );
2157
2158 let done_step: Step<i32, i32> = Step::Done(1);
2159 assert_eq!(
2160 fold_right::<RcFnBrand, StepDoneAppliedBrand<i32>, _, _>(|a, b| a + b, 10, done_step),
2161 10
2162 );
2163 }
2164
2165 #[test]
2171 fn test_traversable_step_with_loop() {
2172 let x = pure::<StepLoopAppliedBrand<()>, _>(5);
2173 assert_eq!(
2174 traverse::<StepLoopAppliedBrand<()>, _, _, OptionBrand>(|a| Some(a * 2), x),
2175 Some(Step::Done(10))
2176 );
2177
2178 let loop_step: Step<i32, i32> = Step::Loop(1);
2179 assert_eq!(
2180 traverse::<StepLoopAppliedBrand<i32>, _, _, OptionBrand>(|a| Some(a * 2), loop_step),
2181 Some(Step::Loop(1))
2182 );
2183 }
2184
2185 #[test]
2189 fn test_traversable_step_with_done() {
2190 let x = pure::<StepDoneAppliedBrand<()>, _>(5);
2191 assert_eq!(
2192 traverse::<StepDoneAppliedBrand<()>, _, _, OptionBrand>(|a| Some(a * 2), x),
2193 Some(Step::Loop(10))
2194 );
2195
2196 let done_step: Step<i32, i32> = Step::Done(1);
2197 assert_eq!(
2198 traverse::<StepDoneAppliedBrand<i32>, _, _, OptionBrand>(|a| Some(a * 2), done_step),
2199 Some(Step::Done(1))
2200 );
2201 }
2202
2203 #[quickcheck]
2207 fn monad_left_identity_step_with_loop(a: i32) -> bool {
2208 let f = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_mul(2));
2209 bind::<StepLoopAppliedBrand<i32>, _, _>(pure::<StepLoopAppliedBrand<i32>, _>(a), f) == f(a)
2210 }
2211
2212 #[quickcheck]
2214 fn monad_right_identity_step_with_loop(x: Step<i32, i32>) -> bool {
2215 bind::<StepLoopAppliedBrand<i32>, _, _>(x, pure::<StepLoopAppliedBrand<i32>, _>) == x
2216 }
2217
2218 #[quickcheck]
2220 fn monad_associativity_step_with_loop(x: Step<i32, i32>) -> bool {
2221 let f = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_mul(2));
2222 let g = |x: i32| pure::<StepLoopAppliedBrand<i32>, _>(x.wrapping_add(1));
2223 bind::<StepLoopAppliedBrand<i32>, _, _>(bind::<StepLoopAppliedBrand<i32>, _, _>(x, f), g)
2224 == bind::<StepLoopAppliedBrand<i32>, _, _>(x, |a| {
2225 bind::<StepLoopAppliedBrand<i32>, _, _>(f(a), g)
2226 })
2227 }
2228
2229 #[quickcheck]
2233 fn monad_left_identity_step_with_done(a: i32) -> bool {
2234 let f = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_mul(2));
2235 bind::<StepDoneAppliedBrand<i32>, _, _>(pure::<StepDoneAppliedBrand<i32>, _>(a), f) == f(a)
2236 }
2237
2238 #[quickcheck]
2240 fn monad_right_identity_step_with_done(x: Step<i32, i32>) -> bool {
2241 bind::<StepDoneAppliedBrand<i32>, _, _>(x, pure::<StepDoneAppliedBrand<i32>, _>) == x
2242 }
2243
2244 #[quickcheck]
2246 fn monad_associativity_step_with_done(x: Step<i32, i32>) -> bool {
2247 let f = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_mul(2));
2248 let g = |x: i32| pure::<StepDoneAppliedBrand<i32>, _>(x.wrapping_add(1));
2249 bind::<StepDoneAppliedBrand<i32>, _, _>(bind::<StepDoneAppliedBrand<i32>, _, _>(x, f), g)
2250 == bind::<StepDoneAppliedBrand<i32>, _, _>(x, |a| {
2251 bind::<StepDoneAppliedBrand<i32>, _, _>(f(a), g)
2252 })
2253 }
2254}