1#[fp_macros::document_module]
20mod inner {
21 use {
22 crate::{
23 Apply,
24 brands::{
25 ControlFlowBrand,
26 ControlFlowBreakAppliedBrand,
27 ControlFlowContinueAppliedBrand,
28 },
29 classes::*,
30 impl_kind,
31 kinds::*,
32 },
33 core::ops::ControlFlow,
34 fp_macros::*,
35 };
36
37 impl ControlFlowBrand {
49 #[document_signature]
51 #[document_type_parameters("The break type.", "The continue type.")]
53 #[document_parameters("The control flow value.")]
55 #[document_returns("`true` if the value is `Continue`, `false` otherwise.")]
57 #[inline]
59 #[document_examples]
60 pub fn is_continue<B, C>(cf: &ControlFlow<B, C>) -> bool {
71 matches!(cf, ControlFlow::Continue(_))
72 }
73
74 #[document_signature]
76 #[document_type_parameters("The break type.", "The continue type.")]
78 #[document_parameters("The control flow value.")]
80 #[document_returns("`true` if the value is `Break`, `false` otherwise.")]
82 #[inline]
84 #[document_examples]
85 pub fn is_break<B, C>(cf: &ControlFlow<B, C>) -> bool {
96 matches!(cf, ControlFlow::Break(_))
97 }
98
99 #[document_signature]
101 #[document_type_parameters(
103 "The break type.",
104 "The original continue type.",
105 "The new continue type."
106 )]
107 #[document_parameters(
109 "The control flow value.",
110 "The function to apply to the continue value."
111 )]
112 #[document_returns("A new `ControlFlow` with the continue value transformed.")]
114 #[document_examples]
116 pub fn map_continue<B, C, C2>(
128 cf: ControlFlow<B, C>,
129 f: impl FnOnce(C) -> C2,
130 ) -> ControlFlow<B, C2> {
131 match cf {
132 ControlFlow::Continue(c) => ControlFlow::Continue(f(c)),
133 ControlFlow::Break(b) => ControlFlow::Break(b),
134 }
135 }
136
137 #[document_signature]
139 #[document_type_parameters(
141 "The original break type.",
142 "The continue type.",
143 "The new break type."
144 )]
145 #[document_parameters(
147 "The control flow value.",
148 "The function to apply to the break value."
149 )]
150 #[document_returns("A new `ControlFlow` with the break value transformed.")]
152 #[document_examples]
154 pub fn map_break<B, C, B2>(
166 cf: ControlFlow<B, C>,
167 f: impl FnOnce(B) -> B2,
168 ) -> ControlFlow<B2, C> {
169 match cf {
170 ControlFlow::Continue(c) => ControlFlow::Continue(c),
171 ControlFlow::Break(b) => ControlFlow::Break(f(b)),
172 }
173 }
174
175 #[document_signature]
177 #[document_type_parameters(
179 "The original break type.",
180 "The original continue type.",
181 "The new break type.",
182 "The new continue type."
183 )]
184 #[document_parameters(
186 "The control flow value.",
187 "The function to apply to the continue value.",
188 "The function to apply to the break value."
189 )]
190 #[document_returns("A new `ControlFlow` with both values transformed.")]
192 #[document_examples]
193 pub fn bimap<B, C, B2, C2>(
205 cf: ControlFlow<B, C>,
206 f: impl FnOnce(C) -> C2,
207 g: impl FnOnce(B) -> B2,
208 ) -> ControlFlow<B2, C2> {
209 match cf {
210 ControlFlow::Continue(c) => ControlFlow::Continue(f(c)),
211 ControlFlow::Break(b) => ControlFlow::Break(g(b)),
212 }
213 }
214
215 #[document_signature]
219 #[document_type_parameters(
221 "The break type.",
222 "The continue type.",
223 "The accumulator type."
224 )]
225 #[document_parameters(
227 "The control flow value.",
228 "The step function for the Continue variant.",
229 "The step function for the Break variant.",
230 "The initial accumulator."
231 )]
232 #[document_returns("The result of folding.")]
234 #[document_examples]
236 pub fn bi_fold_right<B, C, Acc>(
247 cf: ControlFlow<B, C>,
248 f: impl FnOnce(C, Acc) -> Acc,
249 g: impl FnOnce(B, Acc) -> Acc,
250 z: Acc,
251 ) -> Acc {
252 match cf {
253 ControlFlow::Continue(c) => f(c, z),
254 ControlFlow::Break(b) => g(b, z),
255 }
256 }
257
258 #[document_signature]
262 #[document_type_parameters(
264 "The break type.",
265 "The continue type.",
266 "The accumulator type."
267 )]
268 #[document_parameters(
270 "The control flow value.",
271 "The step function for the Continue variant.",
272 "The step function for the Break variant.",
273 "The initial accumulator."
274 )]
275 #[document_returns("The result of folding.")]
277 #[document_examples]
279 pub fn bi_fold_left<B, C, Acc>(
290 cf: ControlFlow<B, C>,
291 f: impl FnOnce(Acc, C) -> Acc,
292 g: impl FnOnce(Acc, B) -> Acc,
293 z: Acc,
294 ) -> Acc {
295 match cf {
296 ControlFlow::Continue(c) => f(z, c),
297 ControlFlow::Break(b) => g(z, b),
298 }
299 }
300
301 #[document_signature]
305 #[document_type_parameters("The break type.", "The continue type.", "The monoid type.")]
307 #[document_parameters(
309 "The control flow value.",
310 "The function mapping the Continue value to the monoid.",
311 "The function mapping the Break value to the monoid."
312 )]
313 #[document_returns("The monoid value.")]
315 #[document_examples]
317 pub fn bi_fold_map<B, C, M>(
331 cf: ControlFlow<B, C>,
332 f: impl FnOnce(C) -> M,
333 g: impl FnOnce(B) -> M,
334 ) -> M {
335 match cf {
336 ControlFlow::Continue(c) => f(c),
337 ControlFlow::Break(b) => g(b),
338 }
339 }
340
341 #[document_signature]
346 #[document_type_parameters(
348 "The break type.",
349 "The continue type.",
350 "The accumulator type."
351 )]
352 #[document_parameters(
354 "The control flow value.",
355 "The function to apply to the Break value and the accumulator.",
356 "The initial accumulator."
357 )]
358 #[document_returns("The result of folding.")]
360 #[document_examples]
362 pub fn fold_right<B, C, Acc>(
373 cf: ControlFlow<B, C>,
374 f: impl FnOnce(B, Acc) -> Acc,
375 initial: Acc,
376 ) -> Acc {
377 match cf {
378 ControlFlow::Continue(_) => initial,
379 ControlFlow::Break(b) => f(b, initial),
380 }
381 }
382
383 #[document_signature]
388 #[document_type_parameters(
390 "The break type.",
391 "The continue type.",
392 "The accumulator type."
393 )]
394 #[document_parameters(
396 "The control flow value.",
397 "The function to apply to the accumulator and the Break value.",
398 "The initial accumulator."
399 )]
400 #[document_returns("The result of folding.")]
402 #[document_examples]
404 pub fn fold_left<B, C, Acc>(
415 cf: ControlFlow<B, C>,
416 f: impl FnOnce(Acc, B) -> Acc,
417 initial: Acc,
418 ) -> Acc {
419 match cf {
420 ControlFlow::Continue(_) => initial,
421 ControlFlow::Break(b) => f(initial, b),
422 }
423 }
424
425 #[document_signature]
430 #[document_type_parameters("The break type.", "The continue type.", "The monoid type.")]
432 #[document_parameters("The control flow value.", "The mapping function.")]
434 #[document_returns("The monoid value.")]
436 #[document_examples]
438 pub fn fold_map<B, C, M: Monoid>(
449 cf: ControlFlow<B, C>,
450 f: impl FnOnce(B) -> M,
451 ) -> M {
452 match cf {
453 ControlFlow::Continue(_) => M::empty(),
454 ControlFlow::Break(b) => f(b),
455 }
456 }
457
458 #[document_signature]
463 #[document_type_parameters(
465 "The original break type.",
466 "The continue type.",
467 "The type of the resulting break value."
468 )]
469 #[document_parameters(
471 "The control flow value.",
472 "The function to apply to the Break value."
473 )]
474 #[document_returns("The result of the computation.")]
476 #[document_examples]
478 pub fn bind_break<B, C, B2>(
490 cf: ControlFlow<B, C>,
491 f: impl FnOnce(B) -> ControlFlow<B2, C>,
492 ) -> ControlFlow<B2, C> {
493 match cf {
494 ControlFlow::Continue(c) => ControlFlow::Continue(c),
495 ControlFlow::Break(b) => f(b),
496 }
497 }
498
499 #[document_signature]
504 #[document_type_parameters(
506 "The break type.",
507 "The original continue type.",
508 "The type of the resulting continue value."
509 )]
510 #[document_parameters(
512 "The control flow value.",
513 "The function to apply to the Continue value."
514 )]
515 #[document_returns("The result of the computation.")]
517 #[document_examples]
519 pub fn bind_continue<B, C, C2>(
531 cf: ControlFlow<B, C>,
532 f: impl FnOnce(C) -> ControlFlow<B, C2>,
533 ) -> ControlFlow<B, C2> {
534 match cf {
535 ControlFlow::Continue(c) => f(c),
536 ControlFlow::Break(b) => ControlFlow::Break(b),
537 }
538 }
539
540 #[document_signature]
542 #[document_type_parameters("The break type.", "The continue type.")]
544 #[document_parameters("The control flow value.")]
546 #[document_returns("`Some(b)` if `Break(b)`, `None` if `Continue(_)`.")]
548 #[inline]
550 #[document_examples]
551 pub fn break_val<B, C>(cf: ControlFlow<B, C>) -> Option<B> {
565 match cf {
566 ControlFlow::Break(b) => Some(b),
567 ControlFlow::Continue(_) => None,
568 }
569 }
570
571 #[document_signature]
573 #[document_type_parameters("The break type.", "The continue type.")]
575 #[document_parameters("The control flow value.")]
577 #[document_returns("`Some(c)` if `Continue(c)`, `None` if `Break(_)`.")]
579 #[inline]
581 #[document_examples]
582 pub fn continue_val<B, C>(cf: ControlFlow<B, C>) -> Option<C> {
596 match cf {
597 ControlFlow::Continue(c) => Some(c),
598 ControlFlow::Break(_) => None,
599 }
600 }
601
602 #[document_signature]
604 #[document_type_parameters("The break type.", "The continue type.")]
606 #[document_parameters("The control flow value.")]
608 #[document_returns("A new `ControlFlow` with the variants swapped.")]
610 #[inline]
612 #[document_examples]
613 pub fn swap<B, C>(cf: ControlFlow<B, C>) -> ControlFlow<C, B> {
627 match cf {
628 ControlFlow::Continue(c) => ControlFlow::Break(c),
629 ControlFlow::Break(b) => ControlFlow::Continue(b),
630 }
631 }
632
633 #[document_signature]
637 #[document_type_parameters(
639 "The lifetime of the values.",
640 "The break type.",
641 "The continue type.",
642 "The output type for the Continue value.",
643 "The output type for the Break value.",
644 "The applicative context."
645 )]
646 #[document_parameters(
648 "The control flow value.",
649 "The function for the Continue value.",
650 "The function for the Break value."
651 )]
652 #[document_returns("The transformed control flow wrapped in the applicative context.")]
654 #[document_examples]
656 pub fn bi_traverse<'a, B: 'a, C: 'a, C2: 'a + Clone, B2: 'a + Clone, F: Applicative>(
675 cf: ControlFlow<B, C>,
676 f: impl Fn(C) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C2>) + 'a,
677 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B2>) + 'a,
678 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B2, C2>>)
679 where
680 ControlFlow<B2, C2>: Clone, {
681 match cf {
682 ControlFlow::Continue(c) => F::map(|c2| ControlFlow::Continue(c2), f(c)),
683 ControlFlow::Break(b) => F::map(|b2| ControlFlow::Break(b2), g(b)),
684 }
685 }
686 }
687
688 impl_kind! {
691 for ControlFlowBrand {
692 type Of<C, B> = ControlFlow<B, C>;
693 }
694 }
695
696 impl_kind! {
697 for ControlFlowBrand {
698 type Of<'a, C: 'a, B: 'a>: 'a = ControlFlow<B, C>;
699 }
700 }
701
702 impl Bifunctor for ControlFlowBrand {
703 #[document_signature]
707 #[document_type_parameters(
709 "The lifetime of the values.",
710 "The type of the continue value.",
711 "The type of the mapped continue value.",
712 "The type of the break value.",
713 "The type of the mapped break value."
714 )]
715 #[document_parameters(
717 "The function to apply to the continue value.",
718 "The function to apply to the break value.",
719 "The control flow to map over."
720 )]
721 #[document_returns("A new control flow containing the mapped values.")]
723 #[document_examples]
724 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
741 f: impl Fn(A) -> B + 'a,
742 g: impl Fn(C) -> D + 'a,
743 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
744 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
745 ControlFlowBrand::bimap(p, f, g)
746 }
747 }
748
749 impl RefBifunctor for ControlFlowBrand {
750 #[document_signature]
756 #[document_type_parameters(
758 "The lifetime of the values.",
759 "The type of the continue value.",
760 "The type of the mapped continue value.",
761 "The type of the break value.",
762 "The type of the mapped break value."
763 )]
764 #[document_parameters(
766 "The function to apply to a reference of the continue value.",
767 "The function to apply to a reference of the break value.",
768 "The control flow to map over by reference."
769 )]
770 #[document_returns("A new control flow containing the mapped values.")]
772 #[document_examples]
773 fn ref_bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
797 f: impl Fn(&A) -> B + 'a,
798 g: impl Fn(&C) -> D + 'a,
799 p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
800 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
801 match p {
802 ControlFlow::Continue(a) => ControlFlow::Continue(f(a)),
803 ControlFlow::Break(c) => ControlFlow::Break(g(c)),
804 }
805 }
806 }
807
808 impl RefBifoldable for ControlFlowBrand {
809 #[document_signature]
814 #[document_type_parameters(
816 "The lifetime of the values.",
817 "The brand of the cloneable function to use.",
818 "The type of the Continue value.",
819 "The type of the Break value.",
820 "The accumulator type."
821 )]
822 #[document_parameters(
824 "The step function for a reference to the Continue variant.",
825 "The step function for a reference to the Break variant.",
826 "The initial accumulator.",
827 "The control flow to fold by reference."
828 )]
829 #[document_returns("The folded result.")]
831 #[document_examples]
832 fn ref_bi_fold_right<'a, FnBrand: LiftFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
863 f: impl Fn(&A, C) -> C + 'a,
864 g: impl Fn(&B, C) -> C + 'a,
865 z: C,
866 p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
867 ) -> C {
868 match p {
869 ControlFlow::Continue(a) => f(a, z),
870 ControlFlow::Break(b) => g(b, z),
871 }
872 }
873 }
874
875 impl RefBitraversable for ControlFlowBrand {
876 #[document_signature]
881 #[document_type_parameters(
883 "The lifetime of the values.",
884 "The brand of the cloneable function wrapper.",
885 "The type of the Continue value.",
886 "The type of the Break value.",
887 "The output type for Continue.",
888 "The output type for Break.",
889 "The applicative context."
890 )]
891 #[document_parameters(
893 "The function applied to a reference of the Continue value.",
894 "The function applied to a reference of the Break value.",
895 "The control flow to traverse by reference."
896 )]
897 #[document_returns(
899 "`f(&a)` wrapped in context for `Continue(a)`, or `g(&b)` wrapped in context for `Break(b)`."
900 )]
901 #[document_examples]
902 fn ref_bi_traverse<
931 'a,
932 FnBrand,
933 A: 'a + Clone,
934 B: 'a + Clone,
935 C: 'a + Clone,
936 D: 'a + Clone,
937 F: Applicative,
938 >(
939 f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
940 g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
941 p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
942 ) -> 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>)>)
943 where
944 FnBrand: LiftFn + 'a,
945 Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>): Clone,
946 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
947 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone, {
948 match p {
949 ControlFlow::Continue(a) => F::map(|c| ControlFlow::Continue(c), f(a)),
950 ControlFlow::Break(b) => F::map(|d| ControlFlow::Break(d), g(b)),
951 }
952 }
953 }
954
955 impl Bifoldable for ControlFlowBrand {
956 #[document_signature]
960 #[document_type_parameters(
962 "The lifetime of the values.",
963 "The brand of the cloneable function to use.",
964 "The type of the Continue value.",
965 "The type of the Break value.",
966 "The accumulator type."
967 )]
968 #[document_parameters(
970 "The step function for the Continue variant.",
971 "The step function for the Break variant.",
972 "The initial accumulator.",
973 "The control flow to fold."
974 )]
975 #[document_returns("The folded result.")]
977 #[document_examples]
978 fn bi_fold_right<'a, FnBrand: CloneFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
999 f: impl Fn(A, C) -> C + 'a,
1000 g: impl Fn(B, C) -> C + 'a,
1001 z: C,
1002 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
1003 ) -> C {
1004 ControlFlowBrand::bi_fold_right(p, f, g, z)
1005 }
1006
1007 #[document_signature]
1011 #[document_type_parameters(
1013 "The lifetime of the values.",
1014 "The brand of the cloneable function to use.",
1015 "The type of the Continue value.",
1016 "The type of the Break value.",
1017 "The accumulator type."
1018 )]
1019 #[document_parameters(
1021 "The step function for the Continue variant.",
1022 "The step function for the Break variant.",
1023 "The initial accumulator.",
1024 "The control flow to fold."
1025 )]
1026 #[document_returns("The folded result.")]
1028 #[document_examples]
1029 fn bi_fold_left<'a, FnBrand: CloneFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
1050 f: impl Fn(C, A) -> C + 'a,
1051 g: impl Fn(C, B) -> C + 'a,
1052 z: C,
1053 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
1054 ) -> C {
1055 ControlFlowBrand::bi_fold_left(p, f, g, z)
1056 }
1057
1058 #[document_signature]
1062 #[document_type_parameters(
1064 "The lifetime of the values.",
1065 "The brand of the cloneable function to use.",
1066 "The type of the Continue value.",
1067 "The type of the Break value.",
1068 "The monoid type."
1069 )]
1070 #[document_parameters(
1072 "The function mapping the Continue value to the monoid.",
1073 "The function mapping the Break value to the monoid.",
1074 "The control flow to fold."
1075 )]
1076 #[document_returns("The monoid value.")]
1078 #[document_examples]
1079 fn bi_fold_map<'a, FnBrand: CloneFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
1099 f: impl Fn(A) -> M + 'a,
1100 g: impl Fn(B) -> M + 'a,
1101 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
1102 ) -> M
1103 where
1104 M: Monoid + 'a, {
1105 ControlFlowBrand::bi_fold_map(p, f, g)
1106 }
1107 }
1108
1109 impl Bitraversable for ControlFlowBrand {
1110 #[document_signature]
1115 #[document_type_parameters(
1117 "The lifetime of the values.",
1118 "The type of the Continue value.",
1119 "The type of the Break value.",
1120 "The output type for Continue.",
1121 "The output type for Break.",
1122 "The applicative context."
1123 )]
1124 #[document_parameters(
1126 "The function applied to the Continue value.",
1127 "The function applied to the Break value.",
1128 "The control flow to traverse."
1129 )]
1130 #[document_returns("The transformed control flow wrapped in the applicative context.")]
1132 #[document_examples]
1133 fn bi_traverse<
1153 'a,
1154 A: 'a + Clone,
1155 B: 'a + Clone,
1156 C: 'a + Clone,
1157 D: 'a + Clone,
1158 F: Applicative,
1159 >(
1160 f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
1161 g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
1162 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
1163 ) -> 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>)>)
1164 {
1165 ControlFlowBrand::bi_traverse::<_, _, C, D, F>(p, f, g)
1166 }
1167 }
1168
1169 impl_kind! {
1172 #[no_inferable_brand]
1173 impl<ContinueType: 'static> for ControlFlowContinueAppliedBrand<ContinueType> {
1174 type Of<'a, B: 'a>: 'a = ControlFlow<B, ContinueType>;
1175 }
1176 }
1177
1178 #[document_type_parameters("The continue type.")]
1179 impl<ContinueType: 'static> Functor for ControlFlowContinueAppliedBrand<ContinueType> {
1180 #[document_signature]
1184 #[document_type_parameters(
1186 "The lifetime of the values.",
1187 "The type of the break value.",
1188 "The type of the result of applying the function."
1189 )]
1190 #[document_parameters(
1192 "The function to apply to the break value.",
1193 "The control flow to map over."
1194 )]
1195 #[document_returns(
1197 "A new control flow containing the result of applying the function to the break value."
1198 )]
1199 #[document_examples]
1201 fn map<'a, A: 'a, B: 'a>(
1220 func: impl Fn(A) -> B + 'a,
1221 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1222 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1223 ControlFlowBrand::map_break(fa, func)
1224 }
1225 }
1226
1227 #[document_type_parameters("The continue type.")]
1228 impl<ContinueType: Clone + 'static> Lift for ControlFlowContinueAppliedBrand<ContinueType> {
1229 #[document_signature]
1233 #[document_type_parameters(
1235 "The lifetime of the values.",
1236 "The type of the first value.",
1237 "The type of the second value.",
1238 "The type of the result."
1239 )]
1240 #[document_parameters(
1242 "The binary function to apply.",
1243 "The first control flow.",
1244 "The second control flow."
1245 )]
1246 #[document_returns(
1248 "`Break(f(a, b))` if both are `Break`, otherwise the first continue encountered."
1249 )]
1250 #[document_examples]
1251 fn lift2<'a, A, B, C>(
1279 func: impl Fn(A, B) -> C + 'a,
1280 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1281 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1282 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1283 where
1284 A: Clone + 'a,
1285 B: Clone + 'a,
1286 C: 'a, {
1287 match (fa, fb) {
1288 (ControlFlow::Break(a), ControlFlow::Break(b)) => ControlFlow::Break(func(a, b)),
1289 (ControlFlow::Continue(e), _) => ControlFlow::Continue(e),
1290 (_, ControlFlow::Continue(e)) => ControlFlow::Continue(e),
1291 }
1292 }
1293 }
1294
1295 #[document_type_parameters("The continue type.")]
1296 impl<ContinueType: 'static> Pointed for ControlFlowContinueAppliedBrand<ContinueType> {
1297 #[document_signature]
1301 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1303 #[document_parameters("The value to wrap.")]
1305 #[document_returns("`Break(a)`.")]
1307 #[document_examples]
1309 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1322 ControlFlow::Break(a)
1323 }
1324 }
1325
1326 #[document_type_parameters("The continue type.")]
1327 impl<ContinueType: Clone + 'static> ApplyFirst for ControlFlowContinueAppliedBrand<ContinueType> {}
1328
1329 #[document_type_parameters("The continue type.")]
1330 impl<ContinueType: Clone + 'static> ApplySecond for ControlFlowContinueAppliedBrand<ContinueType> {}
1331
1332 #[document_type_parameters("The continue type.")]
1333 impl<ContinueType: Clone + 'static> Semiapplicative
1334 for ControlFlowContinueAppliedBrand<ContinueType>
1335 {
1336 #[document_signature]
1340 #[document_type_parameters(
1342 "The lifetime of the values.",
1343 "The brand of the cloneable function wrapper.",
1344 "The type of the input value.",
1345 "The type of the output value."
1346 )]
1347 #[document_parameters(
1349 "The control flow containing the function.",
1350 "The control flow containing the value."
1351 )]
1352 #[document_returns(
1354 "`Break(f(a))` if both are `Break`, otherwise the first continue encountered."
1355 )]
1356 #[document_examples]
1357 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
1375 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1376 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1377 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1378 match (ff, fa) {
1379 (ControlFlow::Break(f), ControlFlow::Break(a)) => ControlFlow::Break(f(a)),
1380 (ControlFlow::Continue(e), _) => ControlFlow::Continue(e),
1381 (_, ControlFlow::Continue(e)) => ControlFlow::Continue(e),
1382 }
1383 }
1384 }
1385
1386 #[document_type_parameters("The continue type.")]
1387 impl<ContinueType: Clone + 'static> Semimonad for ControlFlowContinueAppliedBrand<ContinueType> {
1388 #[document_signature]
1392 #[document_type_parameters(
1394 "The lifetime of the values.",
1395 "The type of the result of the first computation.",
1396 "The type of the result of the second computation."
1397 )]
1398 #[document_parameters(
1400 "The first control flow.",
1401 "The function to apply to the value inside the control flow."
1402 )]
1403 #[document_returns(
1405 "The result of applying `f` to the value if `ma` is `Break`, otherwise the original continue."
1406 )]
1407 #[document_examples]
1408 fn bind<'a, A: 'a, B: 'a>(
1427 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1428 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1429 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1430 ControlFlowBrand::bind_break(ma, func)
1431 }
1432 }
1433
1434 #[document_type_parameters("The continue type.")]
1435 impl<ContinueType: 'static> Foldable for ControlFlowContinueAppliedBrand<ContinueType> {
1436 #[document_signature]
1440 #[document_type_parameters(
1442 "The lifetime of the values.",
1443 "The brand of the cloneable function to use.",
1444 "The type of the elements in the structure.",
1445 "The type of the accumulator."
1446 )]
1447 #[document_parameters(
1449 "The folding function.",
1450 "The initial value.",
1451 "The control flow to fold."
1452 )]
1453 #[document_returns("`func(a, initial)` if `fa` is `Break(a)`, otherwise `initial`.")]
1455 #[document_examples]
1457 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1485 func: impl Fn(A, B) -> B + 'a,
1486 initial: B,
1487 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1488 ) -> B
1489 where
1490 FnBrand: CloneFn + 'a, {
1491 ControlFlowBrand::fold_right(fa, func, initial)
1492 }
1493
1494 #[document_signature]
1498 #[document_type_parameters(
1500 "The lifetime of the values.",
1501 "The brand of the cloneable function to use.",
1502 "The type of the elements in the structure.",
1503 "The type of the accumulator."
1504 )]
1505 #[document_parameters(
1507 "The folding function.",
1508 "The initial value.",
1509 "The control flow to fold."
1510 )]
1511 #[document_returns("`func(initial, a)` if `fa` is `Break(a)`, otherwise `initial`.")]
1513 #[document_examples]
1515 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1543 func: impl Fn(B, A) -> B + 'a,
1544 initial: B,
1545 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1546 ) -> B
1547 where
1548 FnBrand: CloneFn + 'a, {
1549 ControlFlowBrand::fold_left(fa, func, initial)
1550 }
1551
1552 #[document_signature]
1556 #[document_type_parameters(
1558 "The lifetime of the values.",
1559 "The brand of the cloneable function to use.",
1560 "The type of the elements in the structure.",
1561 "The type of the monoid."
1562 )]
1563 #[document_parameters("The mapping function.", "The control flow to fold.")]
1565 #[document_returns("`func(a)` if `fa` is `Break(a)`, otherwise `M::empty()`.")]
1567 #[document_examples]
1569 fn fold_map<'a, FnBrand, A: 'a, M>(
1595 func: impl Fn(A) -> M + 'a,
1596 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1597 ) -> M
1598 where
1599 M: Monoid + 'a,
1600 FnBrand: CloneFn + 'a, {
1601 ControlFlowBrand::fold_map(fa, func)
1602 }
1603 }
1604
1605 #[document_type_parameters("The continue type.")]
1606 impl<ContinueType: Clone + 'static> Traversable for ControlFlowContinueAppliedBrand<ContinueType> {
1607 #[document_signature]
1611 #[document_type_parameters(
1613 "The lifetime of the values.",
1614 "The type of the elements in the traversable structure.",
1615 "The type of the elements in the resulting traversable structure.",
1616 "The applicative context."
1617 )]
1618 #[document_parameters("The function to apply.", "The control flow to traverse.")]
1620 #[document_returns("The control flow wrapped in the applicative context.")]
1622 #[document_examples]
1624 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1655 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1656 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1657 ) -> 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>)>)
1658 where
1659 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1660 match ta {
1661 ControlFlow::Break(a) => F::map(|b| ControlFlow::Break(b), func(a)),
1662 ControlFlow::Continue(e) => F::pure(ControlFlow::Continue(e)),
1663 }
1664 }
1665
1666 #[document_signature]
1670 #[document_type_parameters(
1672 "The lifetime of the values.",
1673 "The type of the elements in the traversable structure.",
1674 "The applicative context."
1675 )]
1676 #[document_parameters("The control flow containing the applicative value.")]
1678 #[document_returns("The control flow wrapped in the applicative context.")]
1680 #[document_examples]
1682 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1707 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>)>)
1708 ) -> 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>)>)
1709 where
1710 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1711 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1712 match ta {
1713 ControlFlow::Break(fa) => F::map(|a| ControlFlow::Break(a), fa),
1714 ControlFlow::Continue(e) => F::pure(ControlFlow::Continue(e)),
1715 }
1716 }
1717 }
1718
1719 impl_kind! {
1722 #[no_inferable_brand]
1723 impl<BreakType: 'static> for ControlFlowBreakAppliedBrand<BreakType> {
1724 type Of<'a, C: 'a>: 'a = ControlFlow<BreakType, C>;
1725 }
1726 }
1727
1728 #[document_type_parameters("The break type.")]
1729 impl<BreakType: 'static> Functor for ControlFlowBreakAppliedBrand<BreakType> {
1730 #[document_signature]
1734 #[document_type_parameters(
1736 "The lifetime of the values.",
1737 "The type of the continue value.",
1738 "The type of the result of applying the function."
1739 )]
1740 #[document_parameters(
1742 "The function to apply to the continue value.",
1743 "The control flow to map over."
1744 )]
1745 #[document_returns(
1747 "A new control flow containing the result of applying the function to the continue value."
1748 )]
1749 #[document_examples]
1751 fn map<'a, A: 'a, B: 'a>(
1770 func: impl Fn(A) -> B + 'a,
1771 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1772 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1773 ControlFlowBrand::map_continue(fa, func)
1774 }
1775 }
1776
1777 #[document_type_parameters("The break type.")]
1778 impl<BreakType: Clone + 'static> Lift for ControlFlowBreakAppliedBrand<BreakType> {
1779 #[document_signature]
1783 #[document_type_parameters(
1785 "The lifetime of the values.",
1786 "The type of the first continue value.",
1787 "The type of the second continue value.",
1788 "The type of the result continue value."
1789 )]
1790 #[document_parameters(
1792 "The binary function to apply to the continues.",
1793 "The first control flow.",
1794 "The second control flow."
1795 )]
1796 #[document_returns(
1798 "`Continue(f(a, b))` if both are `Continue`, otherwise the first break encountered."
1799 )]
1800 #[document_examples]
1801 fn lift2<'a, A, B, C>(
1829 func: impl Fn(A, B) -> C + 'a,
1830 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1831 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1832 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1833 where
1834 A: Clone + 'a,
1835 B: Clone + 'a,
1836 C: 'a, {
1837 match (fa, fb) {
1838 (ControlFlow::Continue(a), ControlFlow::Continue(b)) =>
1839 ControlFlow::Continue(func(a, b)),
1840 (ControlFlow::Break(t), _) => ControlFlow::Break(t),
1841 (_, ControlFlow::Break(t)) => ControlFlow::Break(t),
1842 }
1843 }
1844 }
1845
1846 #[document_type_parameters("The break type.")]
1847 impl<BreakType: 'static> Pointed for ControlFlowBreakAppliedBrand<BreakType> {
1848 #[document_signature]
1852 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1854 #[document_parameters("The value to wrap.")]
1856 #[document_returns("`Continue(a)`.")]
1858 #[document_examples]
1860 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1873 ControlFlow::Continue(a)
1874 }
1875 }
1876
1877 #[document_type_parameters("The break type.")]
1878 impl<BreakType: Clone + 'static> ApplyFirst for ControlFlowBreakAppliedBrand<BreakType> {}
1879
1880 #[document_type_parameters("The break type.")]
1881 impl<BreakType: Clone + 'static> ApplySecond for ControlFlowBreakAppliedBrand<BreakType> {}
1882
1883 #[document_type_parameters("The break type.")]
1884 impl<BreakType: Clone + 'static> Semiapplicative for ControlFlowBreakAppliedBrand<BreakType> {
1885 #[document_signature]
1889 #[document_type_parameters(
1891 "The lifetime of the values.",
1892 "The brand of the cloneable function wrapper.",
1893 "The type of the input value.",
1894 "The type of the output value."
1895 )]
1896 #[document_parameters(
1898 "The control flow containing the function (in Continue).",
1899 "The control flow containing the value (in Continue)."
1900 )]
1901 #[document_returns(
1903 "`Continue(f(a))` if both are `Continue`, otherwise the first break encountered."
1904 )]
1905 #[document_examples]
1906 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
1925 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1926 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1927 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1928 match (ff, fa) {
1929 (ControlFlow::Continue(f), ControlFlow::Continue(a)) => ControlFlow::Continue(f(a)),
1930 (ControlFlow::Break(t), _) => ControlFlow::Break(t),
1931 (_, ControlFlow::Break(t)) => ControlFlow::Break(t),
1932 }
1933 }
1934 }
1935
1936 #[document_type_parameters("The break type.")]
1937 impl<BreakType: Clone + 'static> Semimonad for ControlFlowBreakAppliedBrand<BreakType> {
1938 #[document_signature]
1942 #[document_type_parameters(
1944 "The lifetime of the values.",
1945 "The type of the result of the first computation.",
1946 "The type of the result of the second computation."
1947 )]
1948 #[document_parameters(
1950 "The first control flow.",
1951 "The function to apply to the continue value."
1952 )]
1953 #[document_returns(
1955 "The result of applying `f` to the continue if `ma` is `Continue`, otherwise the original break."
1956 )]
1957 #[document_examples]
1959 fn bind<'a, A: 'a, B: 'a>(
1978 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1979 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1980 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1981 ControlFlowBrand::bind_continue(ma, func)
1982 }
1983 }
1984
1985 #[document_type_parameters("The break type.")]
1986 impl<BreakType: 'static> Foldable for ControlFlowBreakAppliedBrand<BreakType> {
1987 #[document_signature]
1991 #[document_type_parameters(
1993 "The lifetime of the values.",
1994 "The brand of the cloneable function to use.",
1995 "The type of the elements in the structure.",
1996 "The type of the accumulator."
1997 )]
1998 #[document_parameters(
2000 "The folding function.",
2001 "The initial value.",
2002 "The control flow to fold."
2003 )]
2004 #[document_returns("`func(a, initial)` if `fa` is `Continue(a)`, otherwise `initial`.")]
2006 #[document_examples]
2008 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
2036 func: impl Fn(A, B) -> B + 'a,
2037 initial: B,
2038 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2039 ) -> B
2040 where
2041 FnBrand: CloneFn + 'a, {
2042 match fa {
2043 ControlFlow::Continue(e) => func(e, initial),
2044 ControlFlow::Break(_) => initial,
2045 }
2046 }
2047
2048 #[document_signature]
2052 #[document_type_parameters(
2054 "The lifetime of the values.",
2055 "The brand of the cloneable function to use.",
2056 "The type of the elements in the structure.",
2057 "The type of the accumulator."
2058 )]
2059 #[document_parameters(
2061 "The folding function.",
2062 "The initial value.",
2063 "The control flow to fold."
2064 )]
2065 #[document_returns("`func(initial, a)` if `fa` is `Continue(a)`, otherwise `initial`.")]
2067 #[document_examples]
2069 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
2097 func: impl Fn(B, A) -> B + 'a,
2098 initial: B,
2099 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2100 ) -> B
2101 where
2102 FnBrand: CloneFn + 'a, {
2103 match fa {
2104 ControlFlow::Continue(e) => func(initial, e),
2105 ControlFlow::Break(_) => initial,
2106 }
2107 }
2108
2109 #[document_signature]
2113 #[document_type_parameters(
2115 "The lifetime of the values.",
2116 "The brand of the cloneable function to use.",
2117 "The type of the elements in the structure.",
2118 "The type of the monoid."
2119 )]
2120 #[document_parameters("The mapping function.", "The control flow to fold.")]
2122 #[document_returns("`func(a)` if `fa` is `Continue(a)`, otherwise `M::empty()`.")]
2124 #[document_examples]
2126 fn fold_map<'a, FnBrand, A: 'a, M>(
2152 func: impl Fn(A) -> M + 'a,
2153 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2154 ) -> M
2155 where
2156 M: Monoid + 'a,
2157 FnBrand: CloneFn + 'a, {
2158 match fa {
2159 ControlFlow::Continue(e) => func(e),
2160 ControlFlow::Break(_) => M::empty(),
2161 }
2162 }
2163 }
2164
2165 #[document_type_parameters("The break type.")]
2166 impl<BreakType: Clone + 'static> Traversable for ControlFlowBreakAppliedBrand<BreakType> {
2167 #[document_signature]
2171 #[document_type_parameters(
2173 "The lifetime of the values.",
2174 "The type of the elements in the traversable structure.",
2175 "The type of the elements in the resulting traversable structure.",
2176 "The applicative context."
2177 )]
2178 #[document_parameters("The function to apply.", "The control flow to traverse.")]
2180 #[document_returns("The control flow wrapped in the applicative context.")]
2182 #[document_examples]
2184 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
2210 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2211 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2212 ) -> 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>)>)
2213 where
2214 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
2215 match ta {
2216 ControlFlow::Continue(e) => F::map(|b| ControlFlow::Continue(b), func(e)),
2217 ControlFlow::Break(t) => F::pure(ControlFlow::Break(t)),
2218 }
2219 }
2220
2221 #[document_signature]
2225 #[document_type_parameters(
2227 "The lifetime of the values.",
2228 "The type of the elements in the traversable structure.",
2229 "The applicative context."
2230 )]
2231 #[document_parameters("The control flow containing the applicative value.")]
2233 #[document_returns("The control flow wrapped in the applicative context.")]
2235 #[document_examples]
2237 fn sequence<'a, A: 'a + Clone, F: Applicative>(
2262 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>)>)
2263 ) -> 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>)>)
2264 where
2265 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
2266 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
2267 match ta {
2268 ControlFlow::Continue(fe) => F::map(|e| ControlFlow::Continue(e), fe),
2269 ControlFlow::Break(t) => F::pure(ControlFlow::Break(t)),
2270 }
2271 }
2272 }
2273
2274 #[document_type_parameters("The continue type.")]
2276 impl<ContinueType: Clone + 'static> MonadRec for ControlFlowContinueAppliedBrand<ContinueType> {
2277 #[document_signature]
2284 #[document_type_parameters(
2286 "The lifetime of the computation.",
2287 "The type of the initial value and loop state.",
2288 "The type of the result."
2289 )]
2290 #[document_parameters("The step function.", "The initial value.")]
2292 #[document_returns(
2294 "The result of the computation, or a continue if the step function returned `Continue`."
2295 )]
2296 #[document_examples]
2298 fn tail_rec_m<'a, A: 'a, B: 'a>(
2321 func: impl Fn(
2322 A,
2323 )
2324 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
2325 + 'a,
2326 initial: A,
2327 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2328 let mut current = initial;
2329 loop {
2330 match func(current) {
2331 ControlFlow::Continue(l) => return ControlFlow::Continue(l),
2332 ControlFlow::Break(ControlFlow::Continue(next)) => current = next,
2333 ControlFlow::Break(ControlFlow::Break(b)) => return ControlFlow::Break(b),
2334 }
2335 }
2336 }
2337 }
2338
2339 #[document_type_parameters("The break type.")]
2341 impl<BreakType: Clone + 'static> MonadRec for ControlFlowBreakAppliedBrand<BreakType> {
2342 #[document_signature]
2349 #[document_type_parameters(
2351 "The lifetime of the computation.",
2352 "The type of the initial value and loop state.",
2353 "The type of the result."
2354 )]
2355 #[document_parameters("The step function.", "The initial value.")]
2357 #[document_returns(
2359 "The result of the computation, or a break if the step function returned `Break`."
2360 )]
2361 #[document_examples]
2363 fn tail_rec_m<'a, A: 'a, B: 'a>(
2386 func: impl Fn(
2387 A,
2388 )
2389 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
2390 + 'a,
2391 initial: A,
2392 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2393 let mut current = initial;
2394 loop {
2395 match func(current) {
2396 ControlFlow::Break(d) => return ControlFlow::Break(d),
2397 ControlFlow::Continue(ControlFlow::Continue(next)) => current = next,
2398 ControlFlow::Continue(ControlFlow::Break(b)) =>
2399 return ControlFlow::Continue(b),
2400 }
2401 }
2402 }
2403 }
2404}
2405
2406#[cfg(test)]
2407mod tests {
2408 use {
2409 crate::{
2410 brands::*,
2411 functions::*,
2412 },
2413 core::ops::ControlFlow,
2414 quickcheck::{
2415 Arbitrary,
2416 Gen,
2417 },
2418 quickcheck_macros::quickcheck,
2419 };
2420
2421 impl<B: Arbitrary, C: Arbitrary> Arbitrary for ControlFlowWrapper<B, C> {
2422 fn arbitrary(g: &mut Gen) -> Self {
2423 if bool::arbitrary(g) {
2424 ControlFlowWrapper(ControlFlow::Continue(C::arbitrary(g)))
2425 } else {
2426 ControlFlowWrapper(ControlFlow::Break(B::arbitrary(g)))
2427 }
2428 }
2429 }
2430
2431 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
2433 struct ControlFlowWrapper<B, C>(ControlFlow<B, C>);
2434
2435 impl<B, C> ControlFlowWrapper<B, C> {
2436 fn into_inner(self) -> ControlFlow<B, C> {
2437 self.0
2438 }
2439 }
2440
2441 #[test]
2445 fn test_is_continue() {
2446 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2447 assert!(ControlFlowBrand::is_continue(&cf));
2448 assert!(!ControlFlowBrand::is_break(&cf));
2449 }
2450
2451 #[test]
2455 fn test_is_break() {
2456 let cf: ControlFlow<i32, i32> = ControlFlow::Break(1);
2457 assert!(ControlFlowBrand::is_break(&cf));
2458 assert!(!ControlFlowBrand::is_continue(&cf));
2459 }
2460
2461 #[test]
2465 fn test_map_continue() {
2466 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2467 let mapped = ControlFlowBrand::map_continue(cf, |x| x + 1);
2468 assert_eq!(mapped, ControlFlow::Continue(2));
2469
2470 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2471 let mapped_brk = ControlFlowBrand::map_continue(brk, |x| x + 1);
2472 assert_eq!(mapped_brk, ControlFlow::Break(1));
2473 }
2474
2475 #[test]
2479 fn test_map_break() {
2480 let cf: ControlFlow<i32, i32> = ControlFlow::Break(1);
2481 let mapped = ControlFlowBrand::map_break(cf, |x| x + 1);
2482 assert_eq!(mapped, ControlFlow::Break(2));
2483
2484 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2485 let mapped_cont = ControlFlowBrand::map_break(cont, |x| x + 1);
2486 assert_eq!(mapped_cont, ControlFlow::Continue(1));
2487 }
2488
2489 #[test]
2493 fn test_bimap() {
2494 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2495 let mapped = ControlFlowBrand::bimap(cf, |x| x + 1, |x| x * 2);
2496 assert_eq!(mapped, ControlFlow::Continue(2));
2497
2498 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2499 let mapped_brk = ControlFlowBrand::bimap(brk, |x| x + 1, |x| x * 2);
2500 assert_eq!(mapped_brk, ControlFlow::Break(2));
2501 }
2502
2503 #[test]
2505 fn test_functor_with_continue() {
2506 let cf: ControlFlow<i32, i32> = ControlFlow::Break(5);
2507 assert_eq!(
2508 explicit::map::<ControlFlowContinueAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, cf),
2509 ControlFlow::Break(10)
2510 );
2511
2512 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(5);
2513 assert_eq!(
2514 explicit::map::<ControlFlowContinueAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, cont),
2515 ControlFlow::Continue(5)
2516 );
2517 }
2518
2519 #[test]
2521 fn test_functor_with_break() {
2522 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(5);
2523 assert_eq!(
2524 explicit::map::<ControlFlowBreakAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, cf),
2525 ControlFlow::Continue(10)
2526 );
2527
2528 let brk: ControlFlow<i32, i32> = ControlFlow::Break(5);
2529 assert_eq!(
2530 explicit::map::<ControlFlowBreakAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, brk),
2531 ControlFlow::Break(5)
2532 );
2533 }
2534
2535 #[test]
2537 fn test_bifunctor() {
2538 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(5);
2539 assert_eq!(
2540 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((|c| c + 1, |b| b * 2), cf),
2541 ControlFlow::Continue(6)
2542 );
2543
2544 let brk: ControlFlow<i32, i32> = ControlFlow::Break(5);
2545 assert_eq!(
2546 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((|c| c + 1, |b| b * 2), brk),
2547 ControlFlow::Break(10)
2548 );
2549 }
2550
2551 #[quickcheck]
2554 fn functor_identity_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2555 let x = x.into_inner();
2556 explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(identity, x) == x
2557 }
2558
2559 #[quickcheck]
2560 fn functor_composition_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2561 let x = x.into_inner();
2562 let f = |x: i32| x.wrapping_add(1);
2563 let g = |x: i32| x.wrapping_mul(2);
2564 explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(compose(f, g), x)
2565 == explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2566 f,
2567 explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(g, x),
2568 )
2569 }
2570
2571 #[quickcheck]
2574 fn functor_identity_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
2575 let x = x.into_inner();
2576 explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(identity, x) == x
2577 }
2578
2579 #[quickcheck]
2580 fn functor_composition_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
2581 let x = x.into_inner();
2582 let f = |x: i32| x.wrapping_add(1);
2583 let g = |x: i32| x.wrapping_mul(2);
2584 explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(compose(f, g), x)
2585 == explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
2586 f,
2587 explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(g, x),
2588 )
2589 }
2590
2591 #[quickcheck]
2594 fn bifunctor_identity(x: ControlFlowWrapper<i32, i32>) -> bool {
2595 let x = x.into_inner();
2596 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((identity, identity), x) == x
2597 }
2598
2599 #[quickcheck]
2600 fn bifunctor_composition(x: ControlFlowWrapper<i32, i32>) -> bool {
2601 let x = x.into_inner();
2602 let f = |x: i32| x.wrapping_add(1);
2603 let g = |x: i32| x.wrapping_mul(2);
2604 let h = |x: i32| x.wrapping_sub(1);
2605 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
2606
2607 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((compose(f, g), compose(h, i)), x)
2608 == explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>(
2609 (f, h),
2610 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((g, i), x),
2611 )
2612 }
2613
2614 #[test]
2621 fn test_lift2_with_continue() {
2622 let s1: ControlFlow<i32, i32> = ControlFlow::Break(1);
2623 let s2: ControlFlow<i32, i32> = ControlFlow::Break(2);
2624 let s3: ControlFlow<i32, i32> = ControlFlow::Continue(3);
2625
2626 assert_eq!(
2627 explicit::lift2::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _, _, _>(
2628 |x, y| x + y,
2629 s1,
2630 s2
2631 ),
2632 ControlFlow::Break(3)
2633 );
2634 assert_eq!(
2635 explicit::lift2::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _, _, _>(
2636 |x, y| x + y,
2637 s1,
2638 s3
2639 ),
2640 ControlFlow::Continue(3)
2641 );
2642 }
2643
2644 #[test]
2649 fn test_lift2_with_break() {
2650 let s1: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2651 let s2: ControlFlow<i32, i32> = ControlFlow::Continue(2);
2652 let s3: ControlFlow<i32, i32> = ControlFlow::Break(3);
2653
2654 assert_eq!(
2655 explicit::lift2::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _, _, _>(
2656 |x, y| x + y,
2657 s1,
2658 s2
2659 ),
2660 ControlFlow::Continue(3)
2661 );
2662 assert_eq!(
2663 explicit::lift2::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _, _, _>(
2664 |x, y| x + y,
2665 s1,
2666 s3
2667 ),
2668 ControlFlow::Break(3)
2669 );
2670 }
2671
2672 #[test]
2678 fn test_pointed_with_continue() {
2679 assert_eq!(
2680 pure::<ControlFlowContinueAppliedBrand<()>, _>(5),
2681 ControlFlow::<_, ()>::Break(5)
2682 );
2683 }
2684
2685 #[test]
2689 fn test_pointed_with_break() {
2690 assert_eq!(
2691 pure::<ControlFlowBreakAppliedBrand<()>, _>(5),
2692 ControlFlow::<(), _>::Continue(5)
2693 );
2694 }
2695
2696 #[test]
2703 fn test_apply_with_continue() {
2704 let f = pure::<ControlFlowContinueAppliedBrand<()>, _>(lift_fn_new::<RcFnBrand, _, _>(
2705 |x: i32| x * 2,
2706 ));
2707 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2708 assert_eq!(
2709 apply::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _>(f, x),
2710 ControlFlow::Break(10)
2711 );
2712
2713 let cont: ControlFlow<_, i32> = ControlFlow::Continue(1);
2714 let f_cont = pure::<ControlFlowContinueAppliedBrand<i32>, _>(
2715 lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2),
2716 );
2717 assert_eq!(
2718 apply::<RcFnBrand, ControlFlowContinueAppliedBrand<i32>, _, _>(f_cont, cont),
2719 ControlFlow::Continue(1)
2720 );
2721 }
2722
2723 #[test]
2728 fn test_apply_with_break() {
2729 let f = pure::<ControlFlowBreakAppliedBrand<()>, _>(lift_fn_new::<RcFnBrand, _, _>(
2730 |x: i32| x * 2,
2731 ));
2732 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2733 assert_eq!(
2734 apply::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _>(f, x),
2735 ControlFlow::Continue(10)
2736 );
2737
2738 let brk: ControlFlow<i32, _> = ControlFlow::Break(1);
2739 let f_brk = pure::<ControlFlowBreakAppliedBrand<i32>, _>(lift_fn_new::<RcFnBrand, _, _>(
2740 |x: i32| x * 2,
2741 ));
2742 assert_eq!(
2743 apply::<RcFnBrand, ControlFlowBreakAppliedBrand<i32>, _, _>(f_brk, brk),
2744 ControlFlow::Break(1)
2745 );
2746 }
2747
2748 #[test]
2754 fn test_bind_with_continue() {
2755 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2756 assert_eq!(
2757 explicit::bind::<ControlFlowContinueAppliedBrand<()>, _, _, _, _>(x, |i| pure::<
2758 ControlFlowContinueAppliedBrand<()>,
2759 _,
2760 >(i * 2)),
2761 ControlFlow::Break(10)
2762 );
2763
2764 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2765 assert_eq!(
2766 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(cont, |i| pure::<
2767 ControlFlowContinueAppliedBrand<i32>,
2768 _,
2769 >(
2770 i * 2
2771 )),
2772 ControlFlow::Continue(1)
2773 );
2774 }
2775
2776 #[test]
2780 fn test_bind_with_break() {
2781 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2782 assert_eq!(
2783 explicit::bind::<ControlFlowBreakAppliedBrand<()>, _, _, _, _>(x, |i| pure::<
2784 ControlFlowBreakAppliedBrand<()>,
2785 _,
2786 >(i * 2)),
2787 ControlFlow::Continue(10)
2788 );
2789
2790 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2791 assert_eq!(
2792 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(brk, |i| pure::<
2793 ControlFlowBreakAppliedBrand<i32>,
2794 _,
2795 >(i * 2)),
2796 ControlFlow::Break(1)
2797 );
2798 }
2799
2800 #[test]
2806 fn test_foldable_with_continue() {
2807 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2808 assert_eq!(
2809 explicit::fold_right::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _, _, _>(
2810 |a, b| a + b,
2811 10,
2812 x
2813 ),
2814 15
2815 );
2816 assert_eq!(
2817 explicit::fold_left::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _, _, _>(
2818 |b, a| b + a,
2819 10,
2820 x
2821 ),
2822 15
2823 );
2824 assert_eq!(
2825 explicit::fold_map::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _, _, _>(
2826 |a: i32| a.to_string(),
2827 x
2828 ),
2829 "5"
2830 );
2831
2832 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2833 assert_eq!(
2834 explicit::fold_right::<RcFnBrand, ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2835 |a, b| a + b,
2836 10,
2837 cont
2838 ),
2839 10
2840 );
2841 }
2842
2843 #[test]
2847 fn test_foldable_with_break() {
2848 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2849 assert_eq!(
2850 explicit::fold_right::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _, _, _>(
2851 |a, b| a + b,
2852 10,
2853 x
2854 ),
2855 15
2856 );
2857 assert_eq!(
2858 explicit::fold_left::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _, _, _>(
2859 |b, a| b + a,
2860 10,
2861 x
2862 ),
2863 15
2864 );
2865 assert_eq!(
2866 explicit::fold_map::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _, _, _>(
2867 |a: i32| a.to_string(),
2868 x
2869 ),
2870 "5"
2871 );
2872
2873 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2874 assert_eq!(
2875 explicit::fold_right::<RcFnBrand, ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
2876 |a, b| a + b,
2877 10,
2878 brk
2879 ),
2880 10
2881 );
2882 }
2883
2884 #[test]
2890 fn test_traversable_with_continue() {
2891 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2892 assert_eq!(
2893 explicit::traverse::<
2894 RcFnBrand,
2895 ControlFlowContinueAppliedBrand<()>,
2896 _,
2897 _,
2898 OptionBrand,
2899 _,
2900 _,
2901 >(|a| Some(a * 2), x),
2902 Some(ControlFlow::Break(10))
2903 );
2904
2905 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2906 assert_eq!(
2907 explicit::traverse::<
2908 RcFnBrand,
2909 ControlFlowContinueAppliedBrand<i32>,
2910 _,
2911 _,
2912 OptionBrand,
2913 _,
2914 _,
2915 >(|a| Some(a * 2), cont),
2916 Some(ControlFlow::Continue(1))
2917 );
2918 }
2919
2920 #[test]
2924 fn test_traversable_with_break() {
2925 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2926 assert_eq!(
2927 explicit::traverse::<
2928 RcFnBrand,
2929 ControlFlowBreakAppliedBrand<()>,
2930 _,
2931 _,
2932 OptionBrand,
2933 _,
2934 _,
2935 >(|a| Some(a * 2), x),
2936 Some(ControlFlow::Continue(10))
2937 );
2938
2939 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2940 assert_eq!(
2941 explicit::traverse::<
2942 RcFnBrand,
2943 ControlFlowBreakAppliedBrand<i32>,
2944 _,
2945 _,
2946 OptionBrand,
2947 _,
2948 _,
2949 >(|a| Some(a * 2), brk),
2950 Some(ControlFlow::Break(1))
2951 );
2952 }
2953
2954 #[quickcheck]
2958 fn monad_left_identity_with_continue(a: i32) -> bool {
2959 let f = |x: i32| pure::<ControlFlowContinueAppliedBrand<i32>, _>(x.wrapping_mul(2));
2960 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2961 pure::<ControlFlowContinueAppliedBrand<i32>, _>(a),
2962 f,
2963 ) == f(a)
2964 }
2965
2966 #[quickcheck]
2968 fn monad_right_identity_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2969 let x = x.into_inner();
2970 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2971 x,
2972 pure::<ControlFlowContinueAppliedBrand<i32>, _>,
2973 ) == x
2974 }
2975
2976 #[quickcheck]
2978 fn monad_associativity_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2979 let x = x.into_inner();
2980 let f = |x: i32| pure::<ControlFlowContinueAppliedBrand<i32>, _>(x.wrapping_mul(2));
2981 let g = |x: i32| pure::<ControlFlowContinueAppliedBrand<i32>, _>(x.wrapping_add(1));
2982 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2983 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(x, f),
2984 g,
2985 ) == explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(x, |a| {
2986 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(f(a), g)
2987 })
2988 }
2989
2990 #[quickcheck]
2994 fn monad_left_identity_with_break(a: i32) -> bool {
2995 let f = |x: i32| pure::<ControlFlowBreakAppliedBrand<i32>, _>(x.wrapping_mul(2));
2996 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
2997 pure::<ControlFlowBreakAppliedBrand<i32>, _>(a),
2998 f,
2999 ) == f(a)
3000 }
3001
3002 #[quickcheck]
3004 fn monad_right_identity_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
3005 let x = x.into_inner();
3006 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
3007 x,
3008 pure::<ControlFlowBreakAppliedBrand<i32>, _>,
3009 ) == x
3010 }
3011
3012 #[quickcheck]
3014 fn monad_associativity_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
3015 let x = x.into_inner();
3016 let f = |x: i32| pure::<ControlFlowBreakAppliedBrand<i32>, _>(x.wrapping_mul(2));
3017 let g = |x: i32| pure::<ControlFlowBreakAppliedBrand<i32>, _>(x.wrapping_add(1));
3018 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
3019 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(x, f),
3020 g,
3021 ) == explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(x, |a| {
3022 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(f(a), g)
3023 })
3024 }
3025
3026 #[test]
3030 fn test_applicative_continue_applied() {
3031 fn assert_applicative<B: crate::classes::Applicative>() {}
3032 assert_applicative::<ControlFlowContinueAppliedBrand<i32>>();
3033 }
3034
3035 #[test]
3037 fn test_applicative_break_applied() {
3038 fn assert_applicative<B: crate::classes::Applicative>() {}
3039 assert_applicative::<ControlFlowBreakAppliedBrand<i32>>();
3040 }
3041
3042 #[test]
3044 fn test_monad_continue_applied() {
3045 fn assert_monad<B: crate::classes::Monad>() {}
3046 assert_monad::<ControlFlowContinueAppliedBrand<i32>>();
3047 }
3048
3049 #[test]
3051 fn test_monad_break_applied() {
3052 fn assert_monad<B: crate::classes::Monad>() {}
3053 assert_monad::<ControlFlowBreakAppliedBrand<i32>>();
3054 }
3055
3056 #[quickcheck]
3061 fn monad_rec_continue_applied_identity(x: i32) -> bool {
3062 tail_rec_m::<ControlFlowContinueAppliedBrand<()>, _, _>(
3063 |a| ControlFlow::Break(ControlFlow::Break(a)),
3064 x,
3065 ) == ControlFlow::Break(x)
3066 }
3067
3068 #[test]
3071 fn monad_rec_continue_applied_sum_range() {
3072 let result = tail_rec_m::<ControlFlowContinueAppliedBrand<&str>, _, _>(
3073 |(n, acc)| {
3074 if n == 0 {
3075 ControlFlow::Break(ControlFlow::Break(acc))
3076 } else {
3077 ControlFlow::Break(ControlFlow::Continue((n - 1, acc + n)))
3078 }
3079 },
3080 (100i64, 0i64),
3081 );
3082 assert_eq!(result, ControlFlow::Break(5050));
3083 }
3084
3085 #[test]
3087 fn monad_rec_continue_applied_short_circuit() {
3088 let result = tail_rec_m::<ControlFlowContinueAppliedBrand<&str>, _, _>(
3089 |n| {
3090 if n == 5 {
3091 ControlFlow::Continue("stopped")
3092 } else {
3093 ControlFlow::Break(ControlFlow::Continue(n + 1))
3094 }
3095 },
3096 0,
3097 );
3098 assert_eq!(result, ControlFlow::<i32, &str>::Continue("stopped"));
3099 }
3100
3101 #[test]
3104 fn monad_rec_continue_applied_stack_safety() {
3105 let iterations: i64 = 200_000;
3106 let result = tail_rec_m::<ControlFlowContinueAppliedBrand<()>, _, _>(
3107 |acc| {
3108 if acc < iterations {
3109 ControlFlow::Break(ControlFlow::Continue(acc + 1))
3110 } else {
3111 ControlFlow::Break(ControlFlow::Break(acc))
3112 }
3113 },
3114 0i64,
3115 );
3116 assert_eq!(result, ControlFlow::Break(iterations));
3117 }
3118
3119 #[quickcheck]
3124 fn monad_rec_break_applied_identity(x: i32) -> bool {
3125 tail_rec_m::<ControlFlowBreakAppliedBrand<()>, _, _>(
3126 |a| ControlFlow::Continue(ControlFlow::Break(a)),
3127 x,
3128 ) == ControlFlow::Continue(x)
3129 }
3130
3131 #[test]
3134 fn monad_rec_break_applied_sum_range() {
3135 let result = tail_rec_m::<ControlFlowBreakAppliedBrand<&str>, _, _>(
3136 |(n, acc)| {
3137 if n == 0 {
3138 ControlFlow::Continue(ControlFlow::Break(acc))
3139 } else {
3140 ControlFlow::Continue(ControlFlow::Continue((n - 1, acc + n)))
3141 }
3142 },
3143 (100i64, 0i64),
3144 );
3145 assert_eq!(result, ControlFlow::Continue(5050));
3146 }
3147
3148 #[test]
3150 fn monad_rec_break_applied_short_circuit() {
3151 let result = tail_rec_m::<ControlFlowBreakAppliedBrand<&str>, _, _>(
3152 |n| {
3153 if n == 5 {
3154 ControlFlow::Break("stopped")
3155 } else {
3156 ControlFlow::Continue(ControlFlow::Continue(n + 1))
3157 }
3158 },
3159 0,
3160 );
3161 assert_eq!(result, ControlFlow::<&str, i32>::Break("stopped"));
3162 }
3163
3164 #[test]
3167 fn monad_rec_break_applied_stack_safety() {
3168 let iterations: i64 = 200_000;
3169 let result = tail_rec_m::<ControlFlowBreakAppliedBrand<()>, _, _>(
3170 |acc| {
3171 if acc < iterations {
3172 ControlFlow::Continue(ControlFlow::Continue(acc + 1))
3173 } else {
3174 ControlFlow::Continue(ControlFlow::Break(acc))
3175 }
3176 },
3177 0i64,
3178 );
3179 assert_eq!(result, ControlFlow::Continue(iterations));
3180 }
3181
3182 #[test]
3186 fn test_monad_rec_continue_applied() {
3187 fn assert_monad_rec<B: crate::classes::MonadRec>() {}
3188 assert_monad_rec::<ControlFlowContinueAppliedBrand<i32>>();
3189 }
3190
3191 #[test]
3193 fn test_monad_rec_break_applied() {
3194 fn assert_monad_rec<B: crate::classes::MonadRec>() {}
3195 assert_monad_rec::<ControlFlowBreakAppliedBrand<i32>>();
3196 }
3197
3198 #[test]
3202 fn test_break_val() {
3203 let cf: ControlFlow<i32, i32> = ControlFlow::Break(42);
3204 assert_eq!(ControlFlowBrand::break_val(cf), Some(42));
3205
3206 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
3207 assert_eq!(ControlFlowBrand::break_val(cf), None);
3208 }
3209
3210 #[test]
3214 fn test_continue_val() {
3215 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(7);
3216 assert_eq!(ControlFlowBrand::continue_val(cf), Some(7));
3217
3218 let cf: ControlFlow<i32, i32> = ControlFlow::Break(42);
3219 assert_eq!(ControlFlowBrand::continue_val(cf), None);
3220 }
3221
3222 #[test]
3226 fn test_swap() {
3227 let cf: ControlFlow<&str, i32> = ControlFlow::Continue(1);
3228 assert_eq!(ControlFlowBrand::swap(cf), ControlFlow::Break(1));
3229
3230 let cf: ControlFlow<&str, i32> = ControlFlow::Break("hello");
3231 assert_eq!(ControlFlowBrand::swap(cf), ControlFlow::Continue("hello"));
3232 }
3233
3234 #[quickcheck]
3236 fn break_and_continue_val_complementary(x: ControlFlowWrapper<i32, i32>) -> bool {
3237 let cf = x.into_inner();
3238 ControlFlowBrand::break_val(cf).is_some() != ControlFlowBrand::continue_val(cf).is_some()
3239 }
3240
3241 #[quickcheck]
3243 fn swap_involution(x: ControlFlowWrapper<i32, i32>) -> bool {
3244 let cf = x.into_inner();
3245 ControlFlowBrand::swap(ControlFlowBrand::swap(cf)) == cf
3246 }
3247}