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 #[multi_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>(
1378 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1379 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1380 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1381 match (ff, fa) {
1382 (ControlFlow::Break(f), ControlFlow::Break(a)) => ControlFlow::Break(f(a)),
1383 (ControlFlow::Continue(e), _) => ControlFlow::Continue(e),
1384 (_, ControlFlow::Continue(e)) => ControlFlow::Continue(e),
1385 }
1386 }
1387 }
1388
1389 #[document_type_parameters("The continue type.")]
1390 impl<ContinueType: Clone + 'static> Semimonad for ControlFlowContinueAppliedBrand<ContinueType> {
1391 #[document_signature]
1395 #[document_type_parameters(
1397 "The lifetime of the values.",
1398 "The type of the result of the first computation.",
1399 "The type of the result of the second computation."
1400 )]
1401 #[document_parameters(
1403 "The first control flow.",
1404 "The function to apply to the value inside the control flow."
1405 )]
1406 #[document_returns(
1408 "The result of applying `f` to the value if `ma` is `Break`, otherwise the original continue."
1409 )]
1410 #[document_examples]
1411 fn bind<'a, A: 'a, B: 'a>(
1430 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1431 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1432 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1433 ControlFlowBrand::bind_break(ma, func)
1434 }
1435 }
1436
1437 #[document_type_parameters("The continue type.")]
1438 impl<ContinueType: 'static> Foldable for ControlFlowContinueAppliedBrand<ContinueType> {
1439 #[document_signature]
1443 #[document_type_parameters(
1445 "The lifetime of the values.",
1446 "The brand of the cloneable function to use.",
1447 "The type of the elements in the structure.",
1448 "The type of the accumulator."
1449 )]
1450 #[document_parameters(
1452 "The folding function.",
1453 "The initial value.",
1454 "The control flow to fold."
1455 )]
1456 #[document_returns("`func(a, initial)` if `fa` is `Break(a)`, otherwise `initial`.")]
1458 #[document_examples]
1460 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
1488 func: impl Fn(A, B) -> B + 'a,
1489 initial: B,
1490 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1491 ) -> B
1492 where
1493 FnBrand: CloneFn + 'a, {
1494 ControlFlowBrand::fold_right(fa, func, initial)
1495 }
1496
1497 #[document_signature]
1501 #[document_type_parameters(
1503 "The lifetime of the values.",
1504 "The brand of the cloneable function to use.",
1505 "The type of the elements in the structure.",
1506 "The type of the accumulator."
1507 )]
1508 #[document_parameters(
1510 "The folding function.",
1511 "The initial value.",
1512 "The control flow to fold."
1513 )]
1514 #[document_returns("`func(initial, a)` if `fa` is `Break(a)`, otherwise `initial`.")]
1516 #[document_examples]
1518 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
1546 func: impl Fn(B, A) -> B + 'a,
1547 initial: B,
1548 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1549 ) -> B
1550 where
1551 FnBrand: CloneFn + 'a, {
1552 ControlFlowBrand::fold_left(fa, func, initial)
1553 }
1554
1555 #[document_signature]
1559 #[document_type_parameters(
1561 "The lifetime of the values.",
1562 "The brand of the cloneable function to use.",
1563 "The type of the elements in the structure.",
1564 "The type of the monoid."
1565 )]
1566 #[document_parameters("The mapping function.", "The control flow to fold.")]
1568 #[document_returns("`func(a)` if `fa` is `Break(a)`, otherwise `M::empty()`.")]
1570 #[document_examples]
1572 fn fold_map<'a, FnBrand, A: 'a, M>(
1598 func: impl Fn(A) -> M + 'a,
1599 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1600 ) -> M
1601 where
1602 M: Monoid + 'a,
1603 FnBrand: CloneFn + 'a, {
1604 ControlFlowBrand::fold_map(fa, func)
1605 }
1606 }
1607
1608 #[document_type_parameters("The continue type.")]
1609 impl<ContinueType: Clone + 'static> Traversable for ControlFlowContinueAppliedBrand<ContinueType> {
1610 #[document_signature]
1614 #[document_type_parameters(
1616 "The lifetime of the values.",
1617 "The type of the elements in the traversable structure.",
1618 "The type of the elements in the resulting traversable structure.",
1619 "The applicative context."
1620 )]
1621 #[document_parameters("The function to apply.", "The control flow to traverse.")]
1623 #[document_returns("The control flow wrapped in the applicative context.")]
1625 #[document_examples]
1627 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1658 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1659 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1660 ) -> 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>)>)
1661 where
1662 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1663 match ta {
1664 ControlFlow::Break(a) => F::map(|b| ControlFlow::Break(b), func(a)),
1665 ControlFlow::Continue(e) => F::pure(ControlFlow::Continue(e)),
1666 }
1667 }
1668
1669 #[document_signature]
1673 #[document_type_parameters(
1675 "The lifetime of the values.",
1676 "The type of the elements in the traversable structure.",
1677 "The applicative context."
1678 )]
1679 #[document_parameters("The control flow containing the applicative value.")]
1681 #[document_returns("The control flow wrapped in the applicative context.")]
1683 #[document_examples]
1685 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1710 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>)>)
1711 ) -> 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>)>)
1712 where
1713 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1714 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1715 match ta {
1716 ControlFlow::Break(fa) => F::map(|a| ControlFlow::Break(a), fa),
1717 ControlFlow::Continue(e) => F::pure(ControlFlow::Continue(e)),
1718 }
1719 }
1720 }
1721
1722 impl_kind! {
1725 #[multi_brand]
1726 impl<BreakType: 'static> for ControlFlowBreakAppliedBrand<BreakType> {
1727 type Of<'a, C: 'a>: 'a = ControlFlow<BreakType, C>;
1728 }
1729 }
1730
1731 #[document_type_parameters("The break type.")]
1732 impl<BreakType: 'static> Functor for ControlFlowBreakAppliedBrand<BreakType> {
1733 #[document_signature]
1737 #[document_type_parameters(
1739 "The lifetime of the values.",
1740 "The type of the continue value.",
1741 "The type of the result of applying the function."
1742 )]
1743 #[document_parameters(
1745 "The function to apply to the continue value.",
1746 "The control flow to map over."
1747 )]
1748 #[document_returns(
1750 "A new control flow containing the result of applying the function to the continue value."
1751 )]
1752 #[document_examples]
1754 fn map<'a, A: 'a, B: 'a>(
1773 func: impl Fn(A) -> B + 'a,
1774 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1775 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1776 ControlFlowBrand::map_continue(fa, func)
1777 }
1778 }
1779
1780 #[document_type_parameters("The break type.")]
1781 impl<BreakType: Clone + 'static> Lift for ControlFlowBreakAppliedBrand<BreakType> {
1782 #[document_signature]
1786 #[document_type_parameters(
1788 "The lifetime of the values.",
1789 "The type of the first continue value.",
1790 "The type of the second continue value.",
1791 "The type of the result continue value."
1792 )]
1793 #[document_parameters(
1795 "The binary function to apply to the continues.",
1796 "The first control flow.",
1797 "The second control flow."
1798 )]
1799 #[document_returns(
1801 "`Continue(f(a, b))` if both are `Continue`, otherwise the first break encountered."
1802 )]
1803 #[document_examples]
1804 fn lift2<'a, A, B, C>(
1832 func: impl Fn(A, B) -> C + 'a,
1833 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1834 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1835 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1836 where
1837 A: Clone + 'a,
1838 B: Clone + 'a,
1839 C: 'a, {
1840 match (fa, fb) {
1841 (ControlFlow::Continue(a), ControlFlow::Continue(b)) =>
1842 ControlFlow::Continue(func(a, b)),
1843 (ControlFlow::Break(t), _) => ControlFlow::Break(t),
1844 (_, ControlFlow::Break(t)) => ControlFlow::Break(t),
1845 }
1846 }
1847 }
1848
1849 #[document_type_parameters("The break type.")]
1850 impl<BreakType: 'static> Pointed for ControlFlowBreakAppliedBrand<BreakType> {
1851 #[document_signature]
1855 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1857 #[document_parameters("The value to wrap.")]
1859 #[document_returns("`Continue(a)`.")]
1861 #[document_examples]
1863 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1876 ControlFlow::Continue(a)
1877 }
1878 }
1879
1880 #[document_type_parameters("The break type.")]
1881 impl<BreakType: Clone + 'static> ApplyFirst for ControlFlowBreakAppliedBrand<BreakType> {}
1882
1883 #[document_type_parameters("The break type.")]
1884 impl<BreakType: Clone + 'static> ApplySecond for ControlFlowBreakAppliedBrand<BreakType> {}
1885
1886 #[document_type_parameters("The break type.")]
1887 impl<BreakType: Clone + 'static> Semiapplicative for ControlFlowBreakAppliedBrand<BreakType> {
1888 #[document_signature]
1892 #[document_type_parameters(
1894 "The lifetime of the values.",
1895 "The brand of the cloneable function wrapper.",
1896 "The type of the input value.",
1897 "The type of the output value."
1898 )]
1899 #[document_parameters(
1901 "The control flow containing the function (in Continue).",
1902 "The control flow containing the value (in Continue)."
1903 )]
1904 #[document_returns(
1906 "`Continue(f(a))` if both are `Continue`, otherwise the first break encountered."
1907 )]
1908 #[document_examples]
1909 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
1931 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1932 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1933 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1934 match (ff, fa) {
1935 (ControlFlow::Continue(f), ControlFlow::Continue(a)) => ControlFlow::Continue(f(a)),
1936 (ControlFlow::Break(t), _) => ControlFlow::Break(t),
1937 (_, ControlFlow::Break(t)) => ControlFlow::Break(t),
1938 }
1939 }
1940 }
1941
1942 #[document_type_parameters("The break type.")]
1943 impl<BreakType: Clone + 'static> Semimonad for ControlFlowBreakAppliedBrand<BreakType> {
1944 #[document_signature]
1948 #[document_type_parameters(
1950 "The lifetime of the values.",
1951 "The type of the result of the first computation.",
1952 "The type of the result of the second computation."
1953 )]
1954 #[document_parameters(
1956 "The first control flow.",
1957 "The function to apply to the continue value."
1958 )]
1959 #[document_returns(
1961 "The result of applying `f` to the continue if `ma` is `Continue`, otherwise the original break."
1962 )]
1963 #[document_examples]
1965 fn bind<'a, A: 'a, B: 'a>(
1984 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1985 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1986 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1987 ControlFlowBrand::bind_continue(ma, func)
1988 }
1989 }
1990
1991 #[document_type_parameters("The break type.")]
1992 impl<BreakType: 'static> Foldable for ControlFlowBreakAppliedBrand<BreakType> {
1993 #[document_signature]
1997 #[document_type_parameters(
1999 "The lifetime of the values.",
2000 "The brand of the cloneable function to use.",
2001 "The type of the elements in the structure.",
2002 "The type of the accumulator."
2003 )]
2004 #[document_parameters(
2006 "The folding function.",
2007 "The initial value.",
2008 "The control flow to fold."
2009 )]
2010 #[document_returns("`func(a, initial)` if `fa` is `Continue(a)`, otherwise `initial`.")]
2012 #[document_examples]
2014 fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
2042 func: impl Fn(A, B) -> B + 'a,
2043 initial: B,
2044 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2045 ) -> B
2046 where
2047 FnBrand: CloneFn + 'a, {
2048 match fa {
2049 ControlFlow::Continue(e) => func(e, initial),
2050 ControlFlow::Break(_) => initial,
2051 }
2052 }
2053
2054 #[document_signature]
2058 #[document_type_parameters(
2060 "The lifetime of the values.",
2061 "The brand of the cloneable function to use.",
2062 "The type of the elements in the structure.",
2063 "The type of the accumulator."
2064 )]
2065 #[document_parameters(
2067 "The folding function.",
2068 "The initial value.",
2069 "The control flow to fold."
2070 )]
2071 #[document_returns("`func(initial, a)` if `fa` is `Continue(a)`, otherwise `initial`.")]
2073 #[document_examples]
2075 fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
2103 func: impl Fn(B, A) -> B + 'a,
2104 initial: B,
2105 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2106 ) -> B
2107 where
2108 FnBrand: CloneFn + 'a, {
2109 match fa {
2110 ControlFlow::Continue(e) => func(initial, e),
2111 ControlFlow::Break(_) => initial,
2112 }
2113 }
2114
2115 #[document_signature]
2119 #[document_type_parameters(
2121 "The lifetime of the values.",
2122 "The brand of the cloneable function to use.",
2123 "The type of the elements in the structure.",
2124 "The type of the monoid."
2125 )]
2126 #[document_parameters("The mapping function.", "The control flow to fold.")]
2128 #[document_returns("`func(a)` if `fa` is `Continue(a)`, otherwise `M::empty()`.")]
2130 #[document_examples]
2132 fn fold_map<'a, FnBrand, A: 'a, M>(
2158 func: impl Fn(A) -> M + 'a,
2159 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2160 ) -> M
2161 where
2162 M: Monoid + 'a,
2163 FnBrand: CloneFn + 'a, {
2164 match fa {
2165 ControlFlow::Continue(e) => func(e),
2166 ControlFlow::Break(_) => M::empty(),
2167 }
2168 }
2169 }
2170
2171 #[document_type_parameters("The break type.")]
2172 impl<BreakType: Clone + 'static> Traversable for ControlFlowBreakAppliedBrand<BreakType> {
2173 #[document_signature]
2177 #[document_type_parameters(
2179 "The lifetime of the values.",
2180 "The type of the elements in the traversable structure.",
2181 "The type of the elements in the resulting traversable structure.",
2182 "The applicative context."
2183 )]
2184 #[document_parameters("The function to apply.", "The control flow to traverse.")]
2186 #[document_returns("The control flow wrapped in the applicative context.")]
2188 #[document_examples]
2190 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
2216 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2217 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2218 ) -> 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>)>)
2219 where
2220 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
2221 match ta {
2222 ControlFlow::Continue(e) => F::map(|b| ControlFlow::Continue(b), func(e)),
2223 ControlFlow::Break(t) => F::pure(ControlFlow::Break(t)),
2224 }
2225 }
2226
2227 #[document_signature]
2231 #[document_type_parameters(
2233 "The lifetime of the values.",
2234 "The type of the elements in the traversable structure.",
2235 "The applicative context."
2236 )]
2237 #[document_parameters("The control flow containing the applicative value.")]
2239 #[document_returns("The control flow wrapped in the applicative context.")]
2241 #[document_examples]
2243 fn sequence<'a, A: 'a + Clone, F: Applicative>(
2268 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>)>)
2269 ) -> 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>)>)
2270 where
2271 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
2272 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
2273 match ta {
2274 ControlFlow::Continue(fe) => F::map(|e| ControlFlow::Continue(e), fe),
2275 ControlFlow::Break(t) => F::pure(ControlFlow::Break(t)),
2276 }
2277 }
2278 }
2279
2280 #[document_type_parameters("The continue type.")]
2282 impl<ContinueType: Clone + 'static> MonadRec for ControlFlowContinueAppliedBrand<ContinueType> {
2283 #[document_signature]
2290 #[document_type_parameters(
2292 "The lifetime of the computation.",
2293 "The type of the initial value and loop state.",
2294 "The type of the result."
2295 )]
2296 #[document_parameters("The step function.", "The initial value.")]
2298 #[document_returns(
2300 "The result of the computation, or a continue if the step function returned `Continue`."
2301 )]
2302 #[document_examples]
2304 fn tail_rec_m<'a, A: 'a, B: 'a>(
2327 func: impl Fn(
2328 A,
2329 )
2330 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
2331 + 'a,
2332 initial: A,
2333 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2334 let mut current = initial;
2335 loop {
2336 match func(current) {
2337 ControlFlow::Continue(l) => return ControlFlow::Continue(l),
2338 ControlFlow::Break(ControlFlow::Continue(next)) => current = next,
2339 ControlFlow::Break(ControlFlow::Break(b)) => return ControlFlow::Break(b),
2340 }
2341 }
2342 }
2343 }
2344
2345 #[document_type_parameters("The break type.")]
2347 impl<BreakType: Clone + 'static> MonadRec for ControlFlowBreakAppliedBrand<BreakType> {
2348 #[document_signature]
2355 #[document_type_parameters(
2357 "The lifetime of the computation.",
2358 "The type of the initial value and loop state.",
2359 "The type of the result."
2360 )]
2361 #[document_parameters("The step function.", "The initial value.")]
2363 #[document_returns(
2365 "The result of the computation, or a break if the step function returned `Break`."
2366 )]
2367 #[document_examples]
2369 fn tail_rec_m<'a, A: 'a, B: 'a>(
2392 func: impl Fn(
2393 A,
2394 )
2395 -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
2396 + 'a,
2397 initial: A,
2398 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2399 let mut current = initial;
2400 loop {
2401 match func(current) {
2402 ControlFlow::Break(d) => return ControlFlow::Break(d),
2403 ControlFlow::Continue(ControlFlow::Continue(next)) => current = next,
2404 ControlFlow::Continue(ControlFlow::Break(b)) =>
2405 return ControlFlow::Continue(b),
2406 }
2407 }
2408 }
2409 }
2410}
2411
2412#[cfg(test)]
2413mod tests {
2414 use {
2415 crate::{
2416 brands::*,
2417 classes::semiapplicative::apply as explicit_apply,
2418 functions::*,
2419 },
2420 core::ops::ControlFlow,
2421 quickcheck::{
2422 Arbitrary,
2423 Gen,
2424 },
2425 quickcheck_macros::quickcheck,
2426 };
2427
2428 impl<B: Arbitrary, C: Arbitrary> Arbitrary for ControlFlowWrapper<B, C> {
2429 fn arbitrary(g: &mut Gen) -> Self {
2430 if bool::arbitrary(g) {
2431 ControlFlowWrapper(ControlFlow::Continue(C::arbitrary(g)))
2432 } else {
2433 ControlFlowWrapper(ControlFlow::Break(B::arbitrary(g)))
2434 }
2435 }
2436 }
2437
2438 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
2440 struct ControlFlowWrapper<B, C>(ControlFlow<B, C>);
2441
2442 impl<B, C> ControlFlowWrapper<B, C> {
2443 fn into_inner(self) -> ControlFlow<B, C> {
2444 self.0
2445 }
2446 }
2447
2448 #[test]
2452 fn test_is_continue() {
2453 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2454 assert!(ControlFlowBrand::is_continue(&cf));
2455 assert!(!ControlFlowBrand::is_break(&cf));
2456 }
2457
2458 #[test]
2462 fn test_is_break() {
2463 let cf: ControlFlow<i32, i32> = ControlFlow::Break(1);
2464 assert!(ControlFlowBrand::is_break(&cf));
2465 assert!(!ControlFlowBrand::is_continue(&cf));
2466 }
2467
2468 #[test]
2472 fn test_map_continue() {
2473 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2474 let mapped = ControlFlowBrand::map_continue(cf, |x| x + 1);
2475 assert_eq!(mapped, ControlFlow::Continue(2));
2476
2477 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2478 let mapped_brk = ControlFlowBrand::map_continue(brk, |x| x + 1);
2479 assert_eq!(mapped_brk, ControlFlow::Break(1));
2480 }
2481
2482 #[test]
2486 fn test_map_break() {
2487 let cf: ControlFlow<i32, i32> = ControlFlow::Break(1);
2488 let mapped = ControlFlowBrand::map_break(cf, |x| x + 1);
2489 assert_eq!(mapped, ControlFlow::Break(2));
2490
2491 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2492 let mapped_cont = ControlFlowBrand::map_break(cont, |x| x + 1);
2493 assert_eq!(mapped_cont, ControlFlow::Continue(1));
2494 }
2495
2496 #[test]
2500 fn test_bimap() {
2501 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2502 let mapped = ControlFlowBrand::bimap(cf, |x| x + 1, |x| x * 2);
2503 assert_eq!(mapped, ControlFlow::Continue(2));
2504
2505 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2506 let mapped_brk = ControlFlowBrand::bimap(brk, |x| x + 1, |x| x * 2);
2507 assert_eq!(mapped_brk, ControlFlow::Break(2));
2508 }
2509
2510 #[test]
2512 fn test_functor_with_continue() {
2513 let cf: ControlFlow<i32, i32> = ControlFlow::Break(5);
2514 assert_eq!(
2515 explicit::map::<ControlFlowContinueAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, cf),
2516 ControlFlow::Break(10)
2517 );
2518
2519 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(5);
2520 assert_eq!(
2521 explicit::map::<ControlFlowContinueAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, cont),
2522 ControlFlow::Continue(5)
2523 );
2524 }
2525
2526 #[test]
2528 fn test_functor_with_break() {
2529 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(5);
2530 assert_eq!(
2531 explicit::map::<ControlFlowBreakAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, cf),
2532 ControlFlow::Continue(10)
2533 );
2534
2535 let brk: ControlFlow<i32, i32> = ControlFlow::Break(5);
2536 assert_eq!(
2537 explicit::map::<ControlFlowBreakAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, brk),
2538 ControlFlow::Break(5)
2539 );
2540 }
2541
2542 #[test]
2544 fn test_bifunctor() {
2545 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(5);
2546 assert_eq!(
2547 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((|c| c + 1, |b| b * 2), cf),
2548 ControlFlow::Continue(6)
2549 );
2550
2551 let brk: ControlFlow<i32, i32> = ControlFlow::Break(5);
2552 assert_eq!(
2553 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((|c| c + 1, |b| b * 2), brk),
2554 ControlFlow::Break(10)
2555 );
2556 }
2557
2558 #[quickcheck]
2561 fn functor_identity_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2562 let x = x.into_inner();
2563 explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(identity, x) == x
2564 }
2565
2566 #[quickcheck]
2567 fn functor_composition_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2568 let x = x.into_inner();
2569 let f = |x: i32| x.wrapping_add(1);
2570 let g = |x: i32| x.wrapping_mul(2);
2571 explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(compose(f, g), x)
2572 == explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2573 f,
2574 explicit::map::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(g, x),
2575 )
2576 }
2577
2578 #[quickcheck]
2581 fn functor_identity_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
2582 let x = x.into_inner();
2583 explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(identity, x) == x
2584 }
2585
2586 #[quickcheck]
2587 fn functor_composition_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
2588 let x = x.into_inner();
2589 let f = |x: i32| x.wrapping_add(1);
2590 let g = |x: i32| x.wrapping_mul(2);
2591 explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(compose(f, g), x)
2592 == explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
2593 f,
2594 explicit::map::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(g, x),
2595 )
2596 }
2597
2598 #[quickcheck]
2601 fn bifunctor_identity(x: ControlFlowWrapper<i32, i32>) -> bool {
2602 let x = x.into_inner();
2603 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((identity, identity), x) == x
2604 }
2605
2606 #[quickcheck]
2607 fn bifunctor_composition(x: ControlFlowWrapper<i32, i32>) -> bool {
2608 let x = x.into_inner();
2609 let f = |x: i32| x.wrapping_add(1);
2610 let g = |x: i32| x.wrapping_mul(2);
2611 let h = |x: i32| x.wrapping_sub(1);
2612 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
2613
2614 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((compose(f, g), compose(h, i)), x)
2615 == explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>(
2616 (f, h),
2617 explicit::bimap::<ControlFlowBrand, _, _, _, _, _, _>((g, i), x),
2618 )
2619 }
2620
2621 #[test]
2628 fn test_lift2_with_continue() {
2629 let s1: ControlFlow<i32, i32> = ControlFlow::Break(1);
2630 let s2: ControlFlow<i32, i32> = ControlFlow::Break(2);
2631 let s3: ControlFlow<i32, i32> = ControlFlow::Continue(3);
2632
2633 assert_eq!(
2634 explicit::lift2::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _, _, _>(
2635 |x, y| x + y,
2636 s1,
2637 s2
2638 ),
2639 ControlFlow::Break(3)
2640 );
2641 assert_eq!(
2642 explicit::lift2::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _, _, _>(
2643 |x, y| x + y,
2644 s1,
2645 s3
2646 ),
2647 ControlFlow::Continue(3)
2648 );
2649 }
2650
2651 #[test]
2656 fn test_lift2_with_break() {
2657 let s1: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2658 let s2: ControlFlow<i32, i32> = ControlFlow::Continue(2);
2659 let s3: ControlFlow<i32, i32> = ControlFlow::Break(3);
2660
2661 assert_eq!(
2662 explicit::lift2::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _, _, _>(
2663 |x, y| x + y,
2664 s1,
2665 s2
2666 ),
2667 ControlFlow::Continue(3)
2668 );
2669 assert_eq!(
2670 explicit::lift2::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _, _, _>(
2671 |x, y| x + y,
2672 s1,
2673 s3
2674 ),
2675 ControlFlow::Break(3)
2676 );
2677 }
2678
2679 #[test]
2685 fn test_pointed_with_continue() {
2686 assert_eq!(
2687 pure::<ControlFlowContinueAppliedBrand<()>, _>(5),
2688 ControlFlow::<_, ()>::Break(5)
2689 );
2690 }
2691
2692 #[test]
2696 fn test_pointed_with_break() {
2697 assert_eq!(
2698 pure::<ControlFlowBreakAppliedBrand<()>, _>(5),
2699 ControlFlow::<(), _>::Continue(5)
2700 );
2701 }
2702
2703 #[test]
2710 fn test_apply_with_continue() {
2711 let f = pure::<ControlFlowContinueAppliedBrand<()>, _>(lift_fn_new::<RcFnBrand, _, _>(
2712 |x: i32| x * 2,
2713 ));
2714 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2715 assert_eq!(
2716 explicit_apply::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _>(f, x),
2717 ControlFlow::Break(10)
2718 );
2719
2720 let cont: ControlFlow<_, i32> = ControlFlow::Continue(1);
2721 let f_cont = pure::<ControlFlowContinueAppliedBrand<i32>, _>(
2722 lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2),
2723 );
2724 assert_eq!(
2725 explicit_apply::<RcFnBrand, ControlFlowContinueAppliedBrand<i32>, _, _>(f_cont, cont),
2726 ControlFlow::Continue(1)
2727 );
2728 }
2729
2730 #[test]
2735 fn test_apply_with_break() {
2736 let f = pure::<ControlFlowBreakAppliedBrand<()>, _>(lift_fn_new::<RcFnBrand, _, _>(
2737 |x: i32| x * 2,
2738 ));
2739 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2740 assert_eq!(
2741 explicit_apply::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _>(f, x),
2742 ControlFlow::Continue(10)
2743 );
2744
2745 let brk: ControlFlow<i32, _> = ControlFlow::Break(1);
2746 let f_brk = pure::<ControlFlowBreakAppliedBrand<i32>, _>(lift_fn_new::<RcFnBrand, _, _>(
2747 |x: i32| x * 2,
2748 ));
2749 assert_eq!(
2750 explicit_apply::<RcFnBrand, ControlFlowBreakAppliedBrand<i32>, _, _>(f_brk, brk),
2751 ControlFlow::Break(1)
2752 );
2753 }
2754
2755 #[test]
2761 fn test_bind_with_continue() {
2762 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2763 assert_eq!(
2764 explicit::bind::<ControlFlowContinueAppliedBrand<()>, _, _, _, _>(x, |i| pure::<
2765 ControlFlowContinueAppliedBrand<()>,
2766 _,
2767 >(i * 2)),
2768 ControlFlow::Break(10)
2769 );
2770
2771 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2772 assert_eq!(
2773 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(cont, |i| pure::<
2774 ControlFlowContinueAppliedBrand<i32>,
2775 _,
2776 >(
2777 i * 2
2778 )),
2779 ControlFlow::Continue(1)
2780 );
2781 }
2782
2783 #[test]
2787 fn test_bind_with_break() {
2788 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2789 assert_eq!(
2790 explicit::bind::<ControlFlowBreakAppliedBrand<()>, _, _, _, _>(x, |i| pure::<
2791 ControlFlowBreakAppliedBrand<()>,
2792 _,
2793 >(i * 2)),
2794 ControlFlow::Continue(10)
2795 );
2796
2797 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2798 assert_eq!(
2799 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(brk, |i| pure::<
2800 ControlFlowBreakAppliedBrand<i32>,
2801 _,
2802 >(i * 2)),
2803 ControlFlow::Break(1)
2804 );
2805 }
2806
2807 #[test]
2813 fn test_foldable_with_continue() {
2814 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2815 assert_eq!(
2816 explicit::fold_right::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _, _, _>(
2817 |a, b| a + b,
2818 10,
2819 x
2820 ),
2821 15
2822 );
2823 assert_eq!(
2824 explicit::fold_left::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _, _, _>(
2825 |b, a| b + a,
2826 10,
2827 x
2828 ),
2829 15
2830 );
2831 assert_eq!(
2832 explicit::fold_map::<RcFnBrand, ControlFlowContinueAppliedBrand<()>, _, _, _, _>(
2833 |a: i32| a.to_string(),
2834 x
2835 ),
2836 "5"
2837 );
2838
2839 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2840 assert_eq!(
2841 explicit::fold_right::<RcFnBrand, ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2842 |a, b| a + b,
2843 10,
2844 cont
2845 ),
2846 10
2847 );
2848 }
2849
2850 #[test]
2854 fn test_foldable_with_break() {
2855 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2856 assert_eq!(
2857 explicit::fold_right::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _, _, _>(
2858 |a, b| a + b,
2859 10,
2860 x
2861 ),
2862 15
2863 );
2864 assert_eq!(
2865 explicit::fold_left::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _, _, _>(
2866 |b, a| b + a,
2867 10,
2868 x
2869 ),
2870 15
2871 );
2872 assert_eq!(
2873 explicit::fold_map::<RcFnBrand, ControlFlowBreakAppliedBrand<()>, _, _, _, _>(
2874 |a: i32| a.to_string(),
2875 x
2876 ),
2877 "5"
2878 );
2879
2880 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2881 assert_eq!(
2882 explicit::fold_right::<RcFnBrand, ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
2883 |a, b| a + b,
2884 10,
2885 brk
2886 ),
2887 10
2888 );
2889 }
2890
2891 #[test]
2897 fn test_traversable_with_continue() {
2898 let x = pure::<ControlFlowContinueAppliedBrand<()>, _>(5);
2899 assert_eq!(
2900 explicit::traverse::<
2901 RcFnBrand,
2902 ControlFlowContinueAppliedBrand<()>,
2903 _,
2904 _,
2905 OptionBrand,
2906 _,
2907 _,
2908 >(|a| Some(a * 2), x),
2909 Some(ControlFlow::Break(10))
2910 );
2911
2912 let cont: ControlFlow<i32, i32> = ControlFlow::Continue(1);
2913 assert_eq!(
2914 explicit::traverse::<
2915 RcFnBrand,
2916 ControlFlowContinueAppliedBrand<i32>,
2917 _,
2918 _,
2919 OptionBrand,
2920 _,
2921 _,
2922 >(|a| Some(a * 2), cont),
2923 Some(ControlFlow::Continue(1))
2924 );
2925 }
2926
2927 #[test]
2931 fn test_traversable_with_break() {
2932 let x = pure::<ControlFlowBreakAppliedBrand<()>, _>(5);
2933 assert_eq!(
2934 explicit::traverse::<
2935 RcFnBrand,
2936 ControlFlowBreakAppliedBrand<()>,
2937 _,
2938 _,
2939 OptionBrand,
2940 _,
2941 _,
2942 >(|a| Some(a * 2), x),
2943 Some(ControlFlow::Continue(10))
2944 );
2945
2946 let brk: ControlFlow<i32, i32> = ControlFlow::Break(1);
2947 assert_eq!(
2948 explicit::traverse::<
2949 RcFnBrand,
2950 ControlFlowBreakAppliedBrand<i32>,
2951 _,
2952 _,
2953 OptionBrand,
2954 _,
2955 _,
2956 >(|a| Some(a * 2), brk),
2957 Some(ControlFlow::Break(1))
2958 );
2959 }
2960
2961 #[quickcheck]
2965 fn monad_left_identity_with_continue(a: i32) -> bool {
2966 let f = |x: i32| pure::<ControlFlowContinueAppliedBrand<i32>, _>(x.wrapping_mul(2));
2967 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2968 pure::<ControlFlowContinueAppliedBrand<i32>, _>(a),
2969 f,
2970 ) == f(a)
2971 }
2972
2973 #[quickcheck]
2975 fn monad_right_identity_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2976 let x = x.into_inner();
2977 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2978 x,
2979 pure::<ControlFlowContinueAppliedBrand<i32>, _>,
2980 ) == x
2981 }
2982
2983 #[quickcheck]
2985 fn monad_associativity_with_continue(x: ControlFlowWrapper<i32, i32>) -> bool {
2986 let x = x.into_inner();
2987 let f = |x: i32| pure::<ControlFlowContinueAppliedBrand<i32>, _>(x.wrapping_mul(2));
2988 let g = |x: i32| pure::<ControlFlowContinueAppliedBrand<i32>, _>(x.wrapping_add(1));
2989 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(
2990 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(x, f),
2991 g,
2992 ) == explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(x, |a| {
2993 explicit::bind::<ControlFlowContinueAppliedBrand<i32>, _, _, _, _>(f(a), g)
2994 })
2995 }
2996
2997 #[quickcheck]
3001 fn monad_left_identity_with_break(a: i32) -> bool {
3002 let f = |x: i32| pure::<ControlFlowBreakAppliedBrand<i32>, _>(x.wrapping_mul(2));
3003 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
3004 pure::<ControlFlowBreakAppliedBrand<i32>, _>(a),
3005 f,
3006 ) == f(a)
3007 }
3008
3009 #[quickcheck]
3011 fn monad_right_identity_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
3012 let x = x.into_inner();
3013 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
3014 x,
3015 pure::<ControlFlowBreakAppliedBrand<i32>, _>,
3016 ) == x
3017 }
3018
3019 #[quickcheck]
3021 fn monad_associativity_with_break(x: ControlFlowWrapper<i32, i32>) -> bool {
3022 let x = x.into_inner();
3023 let f = |x: i32| pure::<ControlFlowBreakAppliedBrand<i32>, _>(x.wrapping_mul(2));
3024 let g = |x: i32| pure::<ControlFlowBreakAppliedBrand<i32>, _>(x.wrapping_add(1));
3025 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(
3026 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(x, f),
3027 g,
3028 ) == explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(x, |a| {
3029 explicit::bind::<ControlFlowBreakAppliedBrand<i32>, _, _, _, _>(f(a), g)
3030 })
3031 }
3032
3033 #[test]
3037 fn test_applicative_continue_applied() {
3038 fn assert_applicative<B: crate::classes::Applicative>() {}
3039 assert_applicative::<ControlFlowContinueAppliedBrand<i32>>();
3040 }
3041
3042 #[test]
3044 fn test_applicative_break_applied() {
3045 fn assert_applicative<B: crate::classes::Applicative>() {}
3046 assert_applicative::<ControlFlowBreakAppliedBrand<i32>>();
3047 }
3048
3049 #[test]
3051 fn test_monad_continue_applied() {
3052 fn assert_monad<B: crate::classes::Monad>() {}
3053 assert_monad::<ControlFlowContinueAppliedBrand<i32>>();
3054 }
3055
3056 #[test]
3058 fn test_monad_break_applied() {
3059 fn assert_monad<B: crate::classes::Monad>() {}
3060 assert_monad::<ControlFlowBreakAppliedBrand<i32>>();
3061 }
3062
3063 #[quickcheck]
3068 fn monad_rec_continue_applied_identity(x: i32) -> bool {
3069 tail_rec_m::<ControlFlowContinueAppliedBrand<()>, _, _>(
3070 |a| ControlFlow::Break(ControlFlow::Break(a)),
3071 x,
3072 ) == ControlFlow::Break(x)
3073 }
3074
3075 #[test]
3078 fn monad_rec_continue_applied_sum_range() {
3079 let result = tail_rec_m::<ControlFlowContinueAppliedBrand<&str>, _, _>(
3080 |(n, acc)| {
3081 if n == 0 {
3082 ControlFlow::Break(ControlFlow::Break(acc))
3083 } else {
3084 ControlFlow::Break(ControlFlow::Continue((n - 1, acc + n)))
3085 }
3086 },
3087 (100i64, 0i64),
3088 );
3089 assert_eq!(result, ControlFlow::Break(5050));
3090 }
3091
3092 #[test]
3094 fn monad_rec_continue_applied_short_circuit() {
3095 let result = tail_rec_m::<ControlFlowContinueAppliedBrand<&str>, _, _>(
3096 |n| {
3097 if n == 5 {
3098 ControlFlow::Continue("stopped")
3099 } else {
3100 ControlFlow::Break(ControlFlow::Continue(n + 1))
3101 }
3102 },
3103 0,
3104 );
3105 assert_eq!(result, ControlFlow::<i32, &str>::Continue("stopped"));
3106 }
3107
3108 #[test]
3111 fn monad_rec_continue_applied_stack_safety() {
3112 let iterations: i64 = 200_000;
3113 let result = tail_rec_m::<ControlFlowContinueAppliedBrand<()>, _, _>(
3114 |acc| {
3115 if acc < iterations {
3116 ControlFlow::Break(ControlFlow::Continue(acc + 1))
3117 } else {
3118 ControlFlow::Break(ControlFlow::Break(acc))
3119 }
3120 },
3121 0i64,
3122 );
3123 assert_eq!(result, ControlFlow::Break(iterations));
3124 }
3125
3126 #[quickcheck]
3131 fn monad_rec_break_applied_identity(x: i32) -> bool {
3132 tail_rec_m::<ControlFlowBreakAppliedBrand<()>, _, _>(
3133 |a| ControlFlow::Continue(ControlFlow::Break(a)),
3134 x,
3135 ) == ControlFlow::Continue(x)
3136 }
3137
3138 #[test]
3141 fn monad_rec_break_applied_sum_range() {
3142 let result = tail_rec_m::<ControlFlowBreakAppliedBrand<&str>, _, _>(
3143 |(n, acc)| {
3144 if n == 0 {
3145 ControlFlow::Continue(ControlFlow::Break(acc))
3146 } else {
3147 ControlFlow::Continue(ControlFlow::Continue((n - 1, acc + n)))
3148 }
3149 },
3150 (100i64, 0i64),
3151 );
3152 assert_eq!(result, ControlFlow::Continue(5050));
3153 }
3154
3155 #[test]
3157 fn monad_rec_break_applied_short_circuit() {
3158 let result = tail_rec_m::<ControlFlowBreakAppliedBrand<&str>, _, _>(
3159 |n| {
3160 if n == 5 {
3161 ControlFlow::Break("stopped")
3162 } else {
3163 ControlFlow::Continue(ControlFlow::Continue(n + 1))
3164 }
3165 },
3166 0,
3167 );
3168 assert_eq!(result, ControlFlow::<&str, i32>::Break("stopped"));
3169 }
3170
3171 #[test]
3174 fn monad_rec_break_applied_stack_safety() {
3175 let iterations: i64 = 200_000;
3176 let result = tail_rec_m::<ControlFlowBreakAppliedBrand<()>, _, _>(
3177 |acc| {
3178 if acc < iterations {
3179 ControlFlow::Continue(ControlFlow::Continue(acc + 1))
3180 } else {
3181 ControlFlow::Continue(ControlFlow::Break(acc))
3182 }
3183 },
3184 0i64,
3185 );
3186 assert_eq!(result, ControlFlow::Continue(iterations));
3187 }
3188
3189 #[test]
3193 fn test_monad_rec_continue_applied() {
3194 fn assert_monad_rec<B: crate::classes::MonadRec>() {}
3195 assert_monad_rec::<ControlFlowContinueAppliedBrand<i32>>();
3196 }
3197
3198 #[test]
3200 fn test_monad_rec_break_applied() {
3201 fn assert_monad_rec<B: crate::classes::MonadRec>() {}
3202 assert_monad_rec::<ControlFlowBreakAppliedBrand<i32>>();
3203 }
3204
3205 #[test]
3209 fn test_break_val() {
3210 let cf: ControlFlow<i32, i32> = ControlFlow::Break(42);
3211 assert_eq!(ControlFlowBrand::break_val(cf), Some(42));
3212
3213 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(1);
3214 assert_eq!(ControlFlowBrand::break_val(cf), None);
3215 }
3216
3217 #[test]
3221 fn test_continue_val() {
3222 let cf: ControlFlow<i32, i32> = ControlFlow::Continue(7);
3223 assert_eq!(ControlFlowBrand::continue_val(cf), Some(7));
3224
3225 let cf: ControlFlow<i32, i32> = ControlFlow::Break(42);
3226 assert_eq!(ControlFlowBrand::continue_val(cf), None);
3227 }
3228
3229 #[test]
3233 fn test_swap() {
3234 let cf: ControlFlow<&str, i32> = ControlFlow::Continue(1);
3235 assert_eq!(ControlFlowBrand::swap(cf), ControlFlow::Break(1));
3236
3237 let cf: ControlFlow<&str, i32> = ControlFlow::Break("hello");
3238 assert_eq!(ControlFlowBrand::swap(cf), ControlFlow::Continue("hello"));
3239 }
3240
3241 #[quickcheck]
3243 fn break_and_continue_val_complementary(x: ControlFlowWrapper<i32, i32>) -> bool {
3244 let cf = x.into_inner();
3245 ControlFlowBrand::break_val(cf).is_some() != ControlFlowBrand::continue_val(cf).is_some()
3246 }
3247
3248 #[quickcheck]
3250 fn swap_involution(x: ControlFlowWrapper<i32, i32>) -> bool {
3251 let cf = x.into_inner();
3252 ControlFlowBrand::swap(ControlFlowBrand::swap(cf)) == cf
3253 }
3254}