1use crate::{
21 Apply,
22 brands::{StepBrand, StepWithDoneBrand, StepWithLoopBrand},
23 classes::{
24 Applicative, ApplyFirst, ApplySecond, Bifunctor, CloneableFn, Foldable, Functor, Lift,
25 Monoid, ParFoldable, Pointed, Semiapplicative, Semimonad, SendCloneableFn, Traversable,
26 },
27 impl_kind,
28 kinds::*,
29};
30use fp_macros::{doc_params, doc_type_params, hm_signature};
31
32#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
55pub enum Step<A, B> {
56 Loop(A),
58 Done(B),
60}
61
62impl<A, B> Step<A, B> {
63 #[hm_signature]
68 #[inline]
82 pub fn is_loop(&self) -> bool {
83 matches!(self, Step::Loop(_))
84 }
85
86 #[hm_signature]
91 #[inline]
105 pub fn is_done(&self) -> bool {
106 matches!(self, Step::Done(_))
107 }
108
109 #[hm_signature]
114 #[doc_type_params("The new loop type.")]
118 #[doc_params("The function to apply to the loop value.")]
122 pub fn map_loop<C>(
137 self,
138 f: impl FnOnce(A) -> C,
139 ) -> Step<C, B> {
140 match self {
141 Step::Loop(a) => Step::Loop(f(a)),
142 Step::Done(b) => Step::Done(b),
143 }
144 }
145
146 #[hm_signature]
151 #[doc_type_params("The new done type.")]
155 #[doc_params("The function to apply to the done value.")]
159 pub fn map_done<C>(
174 self,
175 f: impl FnOnce(B) -> C,
176 ) -> Step<A, C> {
177 match self {
178 Step::Loop(a) => Step::Loop(a),
179 Step::Done(b) => Step::Done(f(b)),
180 }
181 }
182
183 #[hm_signature]
188 #[doc_type_params("The new loop type.", "The new done type.")]
192 #[doc_params(
196 "The function to apply to the loop value.",
197 "The function to apply to the done value."
198 )]
199 pub fn bimap<C, D>(
214 self,
215 f: impl FnOnce(A) -> C,
216 g: impl FnOnce(B) -> D,
217 ) -> Step<C, D> {
218 match self {
219 Step::Loop(a) => Step::Loop(f(a)),
220 Step::Done(b) => Step::Done(g(b)),
221 }
222 }
223}
224
225impl_kind! {
226 for StepBrand {
227 type Of<A, B> = Step<A, B>;
228 }
229}
230
231impl_kind! {
232 for StepBrand {
233 type Of<'a, A: 'a, B: 'a>: 'a = Step<A, B>;
234 }
235}
236
237impl Bifunctor for StepBrand {
238 #[hm_signature(Bifunctor)]
245 #[doc_type_params(
249 "The lifetime of the values.",
250 "The type of the loop value.",
251 "The type of the mapped loop value.",
252 "The type of the done value.",
253 "The type of the mapped done value.",
254 "The type of the function to apply to the loop value.",
255 "The type of the function to apply to the done value."
256 )]
257 #[doc_params(
261 "The function to apply to the loop value.",
262 "The function to apply to the done value.",
263 "The step to map over."
264 )]
265 fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a, F, G>(
279 f: F,
280 g: G,
281 p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
282 ) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>)
283 where
284 F: Fn(A) -> B + 'a,
285 G: Fn(C) -> D + 'a,
286 {
287 p.bimap(f, g)
288 }
289}
290
291impl_kind! {
294 impl<LoopType: 'static> for StepWithLoopBrand<LoopType> {
295 type Of<'a, B: 'a>: 'a = Step<LoopType, B>;
296 }
297}
298
299impl<LoopType: 'static> Functor for StepWithLoopBrand<LoopType> {
300 #[hm_signature(Functor)]
307 #[doc_type_params(
311 "The lifetime of the values.",
312 "The type of the done value.",
313 "The type of the result of applying the function.",
314 "The type of the function to apply."
315 )]
316 #[doc_params("The function to apply to the done value.", "The step to map over.")]
320 fn map<'a, A: 'a, B: 'a, Func>(
333 func: Func,
334 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
335 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
336 where
337 Func: Fn(A) -> B + 'a,
338 {
339 fa.map_done(func)
340 }
341}
342
343impl<LoopType: Clone + 'static> Lift for StepWithLoopBrand<LoopType> {
344 #[hm_signature(Lift)]
351 #[doc_type_params(
355 "The lifetime of the values.",
356 "The type of the first value.",
357 "The type of the second value.",
358 "The type of the result.",
359 "The type of the binary function."
360 )]
361 #[doc_params("The binary function to apply.", "The first step.", "The second step.")]
365 fn lift2<'a, A, B, C, Func>(
385 func: Func,
386 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
387 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
388 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
389 where
390 Func: Fn(A, B) -> C + 'a,
391 A: Clone + 'a,
392 B: Clone + 'a,
393 C: 'a,
394 {
395 match (fa, fb) {
396 (Step::Done(a), Step::Done(b)) => Step::Done(func(a, b)),
397 (Step::Loop(e), _) => Step::Loop(e),
398 (_, Step::Loop(e)) => Step::Loop(e),
399 }
400 }
401}
402
403impl<LoopType: 'static> Pointed for StepWithLoopBrand<LoopType> {
404 #[hm_signature(Pointed)]
411 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
415 #[doc_params("The value to wrap.")]
419 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
432 Step::Done(a)
433 }
434}
435
436impl<LoopType: Clone + 'static> ApplyFirst for StepWithLoopBrand<LoopType> {}
437impl<LoopType: Clone + 'static> ApplySecond for StepWithLoopBrand<LoopType> {}
438
439impl<LoopType: Clone + 'static> Semiapplicative for StepWithLoopBrand<LoopType> {
440 #[hm_signature(Semiapplicative)]
447 #[doc_type_params(
451 "The lifetime of the values.",
452 "The brand of the cloneable function wrapper.",
453 "The type of the input value.",
454 "The type of the output value."
455 )]
456 #[doc_params("The step containing the function.", "The step containing the value.")]
460 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
474 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
475 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
476 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
477 match (ff, fa) {
478 (Step::Done(f), Step::Done(a)) => Step::Done(f(a)),
479 (Step::Loop(e), _) => Step::Loop(e),
480 (_, Step::Loop(e)) => Step::Loop(e),
481 }
482 }
483}
484
485impl<LoopType: Clone + 'static> Semimonad for StepWithLoopBrand<LoopType> {
486 #[hm_signature(Semimonad)]
493 #[doc_type_params(
497 "The lifetime of the values.",
498 "The type of the result of the first computation.",
499 "The type of the result of the second computation.",
500 "The type of the function to apply."
501 )]
502 #[doc_params("The first step.", "The function to apply to the value inside the step.")]
506 fn bind<'a, A: 'a, B: 'a, Func>(
522 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
523 func: Func,
524 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
525 where
526 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
527 {
528 match ma {
529 Step::Done(a) => func(a),
530 Step::Loop(e) => Step::Loop(e),
531 }
532 }
533}
534
535impl<LoopType: 'static> Foldable for StepWithLoopBrand<LoopType> {
536 #[hm_signature(Foldable)]
543 #[doc_type_params(
547 "The lifetime of the values.",
548 "The brand of the cloneable function to use.",
549 "The type of the elements in the structure.",
550 "The type of the accumulator.",
551 "The type of the folding function."
552 )]
553 #[doc_params("The folding function.", "The initial value.", "The step to fold.")]
557 fn fold_right<'a, FnBrand, A: 'a, B: 'a, F>(
571 func: F,
572 initial: B,
573 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
574 ) -> B
575 where
576 F: Fn(A, B) -> B + 'a,
577 FnBrand: CloneableFn + 'a,
578 {
579 match fa {
580 Step::Done(a) => func(a, initial),
581 Step::Loop(_) => initial,
582 }
583 }
584
585 #[hm_signature(Foldable)]
592 #[doc_type_params(
596 "The lifetime of the values.",
597 "The brand of the cloneable function to use.",
598 "The type of the elements in the structure.",
599 "The type of the accumulator.",
600 "The type of the folding function."
601 )]
602 #[doc_params("The folding function.", "The initial value.", "The step to fold.")]
606 fn fold_left<'a, FnBrand, A: 'a, B: 'a, F>(
620 func: F,
621 initial: B,
622 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
623 ) -> B
624 where
625 F: Fn(B, A) -> B + 'a,
626 FnBrand: CloneableFn + 'a,
627 {
628 match fa {
629 Step::Done(a) => func(initial, a),
630 Step::Loop(_) => initial,
631 }
632 }
633
634 #[hm_signature(Foldable)]
641 #[doc_type_params(
645 "The lifetime of the values.",
646 "The brand of the cloneable function to use.",
647 "The type of the elements in the structure.",
648 "The type of the monoid.",
649 "The type of the mapping function."
650 )]
651 #[doc_params("The mapping function.", "The step to fold.")]
655 fn fold_map<'a, FnBrand, A: 'a, M, F>(
675 func: F,
676 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
677 ) -> M
678 where
679 M: Monoid + 'a,
680 F: Fn(A) -> M + 'a,
681 FnBrand: CloneableFn + 'a,
682 {
683 match fa {
684 Step::Done(a) => func(a),
685 Step::Loop(_) => M::empty(),
686 }
687 }
688}
689
690impl<LoopType: Clone + 'static> Traversable for StepWithLoopBrand<LoopType> {
691 #[hm_signature(Traversable)]
698 #[doc_type_params(
702 "The lifetime of the values.",
703 "The type of the elements in the traversable structure.",
704 "The type of the elements in the resulting traversable structure.",
705 "The applicative context.",
706 "The type of the function to apply."
707 )]
708 #[doc_params("The function to apply.", "The step to traverse.")]
712 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
732 func: Func,
733 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
734 ) -> 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>)>)
735 where
736 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
737 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
738 {
739 match ta {
740 Step::Done(a) => F::map(|b| Step::Done(b), func(a)),
741 Step::Loop(e) => F::pure(Step::Loop(e)),
742 }
743 }
744
745 #[hm_signature(Traversable)]
752 #[doc_type_params(
756 "The lifetime of the values.",
757 "The type of the elements in the traversable structure.",
758 "The applicative context."
759 )]
760 #[doc_params("The step containing the applicative value.")]
764 fn sequence<'a, A: 'a + Clone, F: Applicative>(
784 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>)>)
785 ) -> 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>)>)
786 where
787 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
788 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
789 {
790 match ta {
791 Step::Done(fa) => F::map(|a| Step::Done(a), fa),
792 Step::Loop(e) => F::pure(Step::Loop(e)),
793 }
794 }
795}
796
797impl<LoopType: 'static> ParFoldable for StepWithLoopBrand<LoopType> {
798 #[hm_signature(ParFoldable)]
805 #[doc_type_params(
809 "The lifetime of the values.",
810 "The brand of the cloneable function wrapper.",
811 "The element type.",
812 "The monoid type."
813 )]
814 #[doc_params("The thread-safe function to map each element to a monoid.", "The step to fold.")]
818 fn par_fold_map<'a, FnBrand, A, M>(
836 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
837 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
838 ) -> M
839 where
840 FnBrand: 'a + SendCloneableFn,
841 A: 'a + Clone + Send + Sync,
842 M: Monoid + Send + Sync + 'a,
843 {
844 match fa {
845 Step::Done(a) => func(a),
846 Step::Loop(_) => M::empty(),
847 }
848 }
849
850 #[hm_signature(ParFoldable)]
857 #[doc_type_params(
861 "The lifetime of the values.",
862 "The brand of the cloneable function wrapper.",
863 "The element type.",
864 "The accumulator type."
865 )]
866 #[doc_params(
870 "The thread-safe function to apply to each element and the accumulator.",
871 "The initial value.",
872 "The step to fold."
873 )]
874 fn par_fold_right<'a, FnBrand, A, B>(
892 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
893 initial: B,
894 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
895 ) -> B
896 where
897 FnBrand: 'a + SendCloneableFn,
898 A: 'a + Clone + Send + Sync,
899 B: Send + Sync + 'a,
900 {
901 match fa {
902 Step::Done(a) => func((a, initial)),
903 Step::Loop(_) => initial,
904 }
905 }
906}
907
908impl_kind! {
911 impl<DoneType: 'static> for StepWithDoneBrand<DoneType> {
912 type Of<'a, A: 'a>: 'a = Step<A, DoneType>;
913 }
914}
915
916impl<DoneType: 'static> Functor for StepWithDoneBrand<DoneType> {
917 #[hm_signature(Functor)]
924 #[doc_type_params(
928 "The lifetime of the values.",
929 "The type of the loop value.",
930 "The type of the result of applying the function.",
931 "The type of the function to apply."
932 )]
933 #[doc_params("The function to apply to the loop value.", "The step to map over.")]
937 fn map<'a, A: 'a, B: 'a, Func>(
950 func: Func,
951 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
952 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
953 where
954 Func: Fn(A) -> B + 'a,
955 {
956 fa.map_loop(func)
957 }
958}
959
960impl<DoneType: Clone + 'static> Lift for StepWithDoneBrand<DoneType> {
961 #[hm_signature(Lift)]
968 #[doc_type_params(
972 "The lifetime of the values.",
973 "The type of the first loop value.",
974 "The type of the second loop value.",
975 "The type of the result loop value.",
976 "The type of the binary function."
977 )]
978 #[doc_params(
982 "The binary function to apply to the loops.",
983 "The first step.",
984 "The second step."
985 )]
986 fn lift2<'a, A, B, C, Func>(
1006 func: Func,
1007 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1008 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1009 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1010 where
1011 Func: Fn(A, B) -> C + 'a,
1012 A: Clone + 'a,
1013 B: Clone + 'a,
1014 C: 'a,
1015 {
1016 match (fa, fb) {
1017 (Step::Loop(a), Step::Loop(b)) => Step::Loop(func(a, b)),
1018 (Step::Done(t), _) => Step::Done(t),
1019 (_, Step::Done(t)) => Step::Done(t),
1020 }
1021 }
1022}
1023
1024impl<DoneType: 'static> Pointed for StepWithDoneBrand<DoneType> {
1025 #[hm_signature(Pointed)]
1032 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
1036 #[doc_params("The value to wrap.")]
1040 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1053 Step::Loop(a)
1054 }
1055}
1056
1057impl<DoneType: Clone + 'static> ApplyFirst for StepWithDoneBrand<DoneType> {}
1058impl<DoneType: Clone + 'static> ApplySecond for StepWithDoneBrand<DoneType> {}
1059
1060impl<DoneType: Clone + 'static> Semiapplicative for StepWithDoneBrand<DoneType> {
1061 #[hm_signature(Semiapplicative)]
1068 #[doc_type_params(
1072 "The lifetime of the values.",
1073 "The brand of the cloneable function wrapper.",
1074 "The type of the input value.",
1075 "The type of the output value."
1076 )]
1077 #[doc_params(
1081 "The step containing the function (in Loop).",
1082 "The step containing the value (in Loop)."
1083 )]
1084 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1098 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1099 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1100 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1101 match (ff, fa) {
1102 (Step::Loop(f), Step::Loop(a)) => Step::Loop(f(a)),
1103 (Step::Done(t), _) => Step::Done(t),
1104 (_, Step::Done(t)) => Step::Done(t),
1105 }
1106 }
1107}
1108
1109impl<DoneType: Clone + 'static> Semimonad for StepWithDoneBrand<DoneType> {
1110 #[hm_signature(Semimonad)]
1117 #[doc_type_params(
1121 "The lifetime of the values.",
1122 "The type of the result of the first computation.",
1123 "The type of the result of the second computation.",
1124 "The type of the function to apply."
1125 )]
1126 #[doc_params("The first step.", "The function to apply to the loop value.")]
1130 fn bind<'a, A: 'a, B: 'a, Func>(
1146 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1147 func: Func,
1148 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
1149 where
1150 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1151 {
1152 match ma {
1153 Step::Done(t) => Step::Done(t),
1154 Step::Loop(e) => func(e),
1155 }
1156 }
1157}
1158
1159impl<DoneType: 'static> Foldable for StepWithDoneBrand<DoneType> {
1160 #[hm_signature(Foldable)]
1167 #[doc_type_params(
1171 "The lifetime of the values.",
1172 "The brand of the cloneable function to use.",
1173 "The type of the elements in the structure.",
1174 "The type of the accumulator.",
1175 "The type of the folding function."
1176 )]
1177 #[doc_params("The folding function.", "The initial value.", "The step to fold.")]
1181 fn fold_right<'a, FnBrand, A: 'a, B: 'a, F>(
1195 func: F,
1196 initial: B,
1197 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1198 ) -> B
1199 where
1200 F: Fn(A, B) -> B + 'a,
1201 FnBrand: CloneableFn + 'a,
1202 {
1203 match fa {
1204 Step::Loop(e) => func(e, initial),
1205 Step::Done(_) => initial,
1206 }
1207 }
1208
1209 #[hm_signature(Foldable)]
1216 #[doc_type_params(
1220 "The lifetime of the values.",
1221 "The brand of the cloneable function to use.",
1222 "The type of the elements in the structure.",
1223 "The type of the accumulator.",
1224 "The type of the folding function."
1225 )]
1226 #[doc_params("The folding function.", "The initial value.", "The step to fold.")]
1230 fn fold_left<'a, FnBrand, A: 'a, B: 'a, F>(
1244 func: F,
1245 initial: B,
1246 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1247 ) -> B
1248 where
1249 F: Fn(B, A) -> B + 'a,
1250 FnBrand: CloneableFn + 'a,
1251 {
1252 match fa {
1253 Step::Loop(e) => func(initial, e),
1254 Step::Done(_) => initial,
1255 }
1256 }
1257
1258 #[hm_signature(Foldable)]
1265 #[doc_type_params(
1269 "The lifetime of the values.",
1270 "The brand of the cloneable function to use.",
1271 "The type of the elements in the structure.",
1272 "The type of the monoid.",
1273 "The type of the mapping function."
1274 )]
1275 #[doc_params("The mapping function.", "The step to fold.")]
1279 fn fold_map<'a, FnBrand, A: 'a, M, F>(
1299 func: F,
1300 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1301 ) -> M
1302 where
1303 M: Monoid + 'a,
1304 F: Fn(A) -> M + 'a,
1305 FnBrand: CloneableFn + 'a,
1306 {
1307 match fa {
1308 Step::Loop(e) => func(e),
1309 Step::Done(_) => M::empty(),
1310 }
1311 }
1312}
1313
1314impl<DoneType: Clone + 'static> Traversable for StepWithDoneBrand<DoneType> {
1315 #[hm_signature(Traversable)]
1322 #[doc_type_params(
1326 "The lifetime of the values.",
1327 "The type of the elements in the traversable structure.",
1328 "The type of the elements in the resulting traversable structure.",
1329 "The applicative context.",
1330 "The type of the function to apply."
1331 )]
1332 #[doc_params("The function to apply.", "The step to traverse.")]
1336 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
1356 func: Func,
1357 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1358 ) -> 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>)>)
1359 where
1360 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1361 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1362 {
1363 match ta {
1364 Step::Loop(e) => F::map(|b| Step::Loop(b), func(e)),
1365 Step::Done(t) => F::pure(Step::Done(t)),
1366 }
1367 }
1368
1369 #[hm_signature(Traversable)]
1376 #[doc_type_params(
1380 "The lifetime of the values.",
1381 "The type of the elements in the traversable structure.",
1382 "The applicative context."
1383 )]
1384 #[doc_params("The step containing the applicative value.")]
1388 fn sequence<'a, A: 'a + Clone, F: Applicative>(
1408 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>)>)
1409 ) -> 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>)>)
1410 where
1411 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1412 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1413 {
1414 match ta {
1415 Step::Loop(fe) => F::map(|e| Step::Loop(e), fe),
1416 Step::Done(t) => F::pure(Step::Done(t)),
1417 }
1418 }
1419}
1420
1421impl<DoneType: 'static> ParFoldable for StepWithDoneBrand<DoneType> {
1422 #[hm_signature(ParFoldable)]
1429 #[doc_type_params(
1433 "The lifetime of the values.",
1434 "The brand of the cloneable function wrapper.",
1435 "The element type.",
1436 "The monoid type."
1437 )]
1438 #[doc_params("The thread-safe function to map each element to a monoid.", "The step to fold.")]
1442 fn par_fold_map<'a, FnBrand, A, M>(
1460 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1461 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1462 ) -> M
1463 where
1464 FnBrand: 'a + SendCloneableFn,
1465 A: 'a + Clone + Send + Sync,
1466 M: Monoid + Send + Sync + 'a,
1467 {
1468 match fa {
1469 Step::Loop(e) => func(e),
1470 Step::Done(_) => M::empty(),
1471 }
1472 }
1473
1474 #[hm_signature(ParFoldable)]
1481 #[doc_type_params(
1485 "The lifetime of the values.",
1486 "The brand of the cloneable function wrapper.",
1487 "The element type.",
1488 "The accumulator type."
1489 )]
1490 #[doc_params(
1494 "The thread-safe function to apply to each element and the accumulator.",
1495 "The initial value.",
1496 "The step to fold."
1497 )]
1498 fn par_fold_right<'a, FnBrand, A, B>(
1516 func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1517 initial: B,
1518 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1519 ) -> B
1520 where
1521 FnBrand: 'a + SendCloneableFn,
1522 A: 'a + Clone + Send + Sync,
1523 B: Send + Sync + 'a,
1524 {
1525 match fa {
1526 Step::Loop(e) => func((e, initial)),
1527 Step::Done(_) => initial,
1528 }
1529 }
1530}
1531
1532#[cfg(test)]
1533mod tests {
1534 use super::*;
1535 use crate::{
1536 brands::*,
1537 classes::{
1538 bifunctor::*, foldable::*, functor::*, lift::*, par_foldable::*, pointed::*,
1539 semiapplicative::*, semimonad::*, traversable::*,
1540 },
1541 functions::*,
1542 };
1543 use quickcheck::{Arbitrary, Gen};
1544 use quickcheck_macros::quickcheck;
1545
1546 impl<A: Arbitrary, B: Arbitrary> Arbitrary for Step<A, B> {
1547 fn arbitrary(g: &mut Gen) -> Self {
1548 if bool::arbitrary(g) {
1549 Step::Loop(A::arbitrary(g))
1550 } else {
1551 Step::Done(B::arbitrary(g))
1552 }
1553 }
1554 }
1555
1556 #[test]
1560 fn test_is_loop() {
1561 let step: Step<i32, i32> = Step::Loop(1);
1562 assert!(step.is_loop());
1563 assert!(!step.is_done());
1564 }
1565
1566 #[test]
1570 fn test_is_done() {
1571 let step: Step<i32, i32> = Step::Done(1);
1572 assert!(step.is_done());
1573 assert!(!step.is_loop());
1574 }
1575
1576 #[test]
1580 fn test_map_loop() {
1581 let step: Step<i32, i32> = Step::Loop(1);
1582 let mapped = step.map_loop(|x| x + 1);
1583 assert_eq!(mapped, Step::Loop(2));
1584
1585 let done: Step<i32, i32> = Step::Done(1);
1586 let mapped_done = done.map_loop(|x| x + 1);
1587 assert_eq!(mapped_done, Step::Done(1));
1588 }
1589
1590 #[test]
1594 fn test_map_done() {
1595 let step: Step<i32, i32> = Step::Done(1);
1596 let mapped = step.map_done(|x| x + 1);
1597 assert_eq!(mapped, Step::Done(2));
1598
1599 let loop_step: Step<i32, i32> = Step::Loop(1);
1600 let mapped_loop = loop_step.map_done(|x| x + 1);
1601 assert_eq!(mapped_loop, Step::Loop(1));
1602 }
1603
1604 #[test]
1608 fn test_bimap() {
1609 let step: Step<i32, i32> = Step::Loop(1);
1610 let mapped = step.bimap(|x| x + 1, |x| x * 2);
1611 assert_eq!(mapped, Step::Loop(2));
1612
1613 let done: Step<i32, i32> = Step::Done(1);
1614 let mapped_done = done.bimap(|x| x + 1, |x| x * 2);
1615 assert_eq!(mapped_done, Step::Done(2));
1616 }
1617
1618 #[test]
1620 fn test_functor_step_with_loop() {
1621 let step: Step<i32, i32> = Step::Done(5);
1622 assert_eq!(map::<StepWithLoopBrand<_>, _, _, _>(|x: i32| x * 2, step), Step::Done(10));
1623
1624 let loop_step: Step<i32, i32> = Step::Loop(5);
1625 assert_eq!(map::<StepWithLoopBrand<_>, _, _, _>(|x: i32| x * 2, loop_step), Step::Loop(5));
1626 }
1627
1628 #[test]
1630 fn test_functor_step_with_done() {
1631 let step: Step<i32, i32> = Step::Loop(5);
1632 assert_eq!(map::<StepWithDoneBrand<_>, _, _, _>(|x: i32| x * 2, step), Step::Loop(10));
1633
1634 let done_step: Step<i32, i32> = Step::Done(5);
1635 assert_eq!(map::<StepWithDoneBrand<_>, _, _, _>(|x: i32| x * 2, done_step), Step::Done(5));
1636 }
1637
1638 #[test]
1640 fn test_bifunctor_step() {
1641 let step: Step<i32, i32> = Step::Loop(5);
1642 assert_eq!(bimap::<StepBrand, _, _, _, _, _, _>(|a| a + 1, |b| b * 2, step), Step::Loop(6));
1643
1644 let done: Step<i32, i32> = Step::Done(5);
1645 assert_eq!(
1646 bimap::<StepBrand, _, _, _, _, _, _>(|a| a + 1, |b| b * 2, done),
1647 Step::Done(10)
1648 );
1649 }
1650
1651 #[quickcheck]
1654 fn functor_identity_step_with_loop(x: Step<i32, i32>) -> bool {
1655 map::<StepWithLoopBrand<i32>, _, _, _>(identity, x) == x
1656 }
1657
1658 #[quickcheck]
1659 fn functor_composition_step_with_loop(x: Step<i32, i32>) -> bool {
1660 let f = |x: i32| x.wrapping_add(1);
1661 let g = |x: i32| x.wrapping_mul(2);
1662 map::<StepWithLoopBrand<i32>, _, _, _>(compose(f, g), x)
1663 == map::<StepWithLoopBrand<i32>, _, _, _>(
1664 f,
1665 map::<StepWithLoopBrand<i32>, _, _, _>(g, x),
1666 )
1667 }
1668
1669 #[quickcheck]
1672 fn functor_identity_step_with_done(x: Step<i32, i32>) -> bool {
1673 map::<StepWithDoneBrand<i32>, _, _, _>(identity, x) == x
1674 }
1675
1676 #[quickcheck]
1677 fn functor_composition_step_with_done(x: Step<i32, i32>) -> bool {
1678 let f = |x: i32| x.wrapping_add(1);
1679 let g = |x: i32| x.wrapping_mul(2);
1680 map::<StepWithDoneBrand<i32>, _, _, _>(compose(f, g), x)
1681 == map::<StepWithDoneBrand<i32>, _, _, _>(
1682 f,
1683 map::<StepWithDoneBrand<i32>, _, _, _>(g, x),
1684 )
1685 }
1686
1687 #[quickcheck]
1690 fn bifunctor_identity_step(x: Step<i32, i32>) -> bool {
1691 bimap::<StepBrand, _, _, _, _, _, _>(identity, identity, x) == x
1692 }
1693
1694 #[quickcheck]
1695 fn bifunctor_composition_step(x: Step<i32, i32>) -> bool {
1696 let f = |x: i32| x.wrapping_add(1);
1697 let g = |x: i32| x.wrapping_mul(2);
1698 let h = |x: i32| x.wrapping_sub(1);
1699 let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1700
1701 bimap::<StepBrand, _, _, _, _, _, _>(compose(f, g), compose(h, i), x)
1702 == bimap::<StepBrand, _, _, _, _, _, _>(
1703 f,
1704 h,
1705 bimap::<StepBrand, _, _, _, _, _, _>(g, i, x),
1706 )
1707 }
1708
1709 #[test]
1716 fn test_lift2_step_with_loop() {
1717 let s1: Step<i32, i32> = Step::Done(1);
1718 let s2: Step<i32, i32> = Step::Done(2);
1719 let s3: Step<i32, i32> = Step::Loop(3);
1720
1721 assert_eq!(
1722 lift2::<StepWithLoopBrand<i32>, _, _, _, _>(|x, y| x + y, s1, s2),
1723 Step::Done(3)
1724 );
1725 assert_eq!(
1726 lift2::<StepWithLoopBrand<i32>, _, _, _, _>(|x, y| x + y, s1, s3),
1727 Step::Loop(3)
1728 );
1729 }
1730
1731 #[test]
1736 fn test_lift2_step_with_done() {
1737 let s1: Step<i32, i32> = Step::Loop(1);
1738 let s2: Step<i32, i32> = Step::Loop(2);
1739 let s3: Step<i32, i32> = Step::Done(3);
1740
1741 assert_eq!(
1742 lift2::<StepWithDoneBrand<i32>, _, _, _, _>(|x, y| x + y, s1, s2),
1743 Step::Loop(3)
1744 );
1745 assert_eq!(
1746 lift2::<StepWithDoneBrand<i32>, _, _, _, _>(|x, y| x + y, s1, s3),
1747 Step::Done(3)
1748 );
1749 }
1750
1751 #[test]
1757 fn test_pointed_step_with_loop() {
1758 assert_eq!(pure::<StepWithLoopBrand<()>, _>(5), Step::Done(5));
1759 }
1760
1761 #[test]
1765 fn test_pointed_step_with_done() {
1766 assert_eq!(pure::<StepWithDoneBrand<()>, _>(5), Step::Loop(5));
1767 }
1768
1769 #[test]
1776 fn test_apply_step_with_loop() {
1777 let f =
1778 pure::<StepWithLoopBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
1779 let x = pure::<StepWithLoopBrand<()>, _>(5);
1780 assert_eq!(apply::<RcFnBrand, StepWithLoopBrand<()>, _, _>(f, x), Step::Done(10));
1781
1782 let loop_step: Step<i32, _> = Step::Loop(1);
1783 let f_loop =
1784 pure::<StepWithLoopBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
1785 assert_eq!(
1786 apply::<RcFnBrand, StepWithLoopBrand<i32>, _, _>(f_loop, loop_step),
1787 Step::Loop(1)
1788 );
1789 }
1790
1791 #[test]
1796 fn test_apply_step_with_done() {
1797 let f =
1798 pure::<StepWithDoneBrand<()>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
1799 let x = pure::<StepWithDoneBrand<()>, _>(5);
1800 assert_eq!(apply::<RcFnBrand, StepWithDoneBrand<()>, _, _>(f, x), Step::Loop(10));
1801
1802 let done_step: Step<_, i32> = Step::Done(1);
1803 let f_done =
1804 pure::<StepWithDoneBrand<i32>, _>(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
1805 assert_eq!(
1806 apply::<RcFnBrand, StepWithDoneBrand<i32>, _, _>(f_done, done_step),
1807 Step::Done(1)
1808 );
1809 }
1810
1811 #[test]
1817 fn test_bind_step_with_loop() {
1818 let x = pure::<StepWithLoopBrand<()>, _>(5);
1819 assert_eq!(
1820 bind::<StepWithLoopBrand<()>, _, _, _>(x, |i| pure::<StepWithLoopBrand<()>, _>(i * 2)),
1821 Step::Done(10)
1822 );
1823
1824 let loop_step: Step<i32, i32> = Step::Loop(1);
1825 assert_eq!(
1826 bind::<StepWithLoopBrand<i32>, _, _, _>(
1827 loop_step,
1828 |i| pure::<StepWithLoopBrand<i32>, _>(i * 2)
1829 ),
1830 Step::Loop(1)
1831 );
1832 }
1833
1834 #[test]
1838 fn test_bind_step_with_done() {
1839 let x = pure::<StepWithDoneBrand<()>, _>(5);
1840 assert_eq!(
1841 bind::<StepWithDoneBrand<()>, _, _, _>(x, |i| pure::<StepWithDoneBrand<()>, _>(i * 2)),
1842 Step::Loop(10)
1843 );
1844
1845 let done_step: Step<i32, i32> = Step::Done(1);
1846 assert_eq!(
1847 bind::<StepWithDoneBrand<i32>, _, _, _>(
1848 done_step,
1849 |i| pure::<StepWithDoneBrand<i32>, _>(i * 2)
1850 ),
1851 Step::Done(1)
1852 );
1853 }
1854
1855 #[test]
1861 fn test_foldable_step_with_loop() {
1862 let x = pure::<StepWithLoopBrand<()>, _>(5);
1863 assert_eq!(
1864 fold_right::<RcFnBrand, StepWithLoopBrand<()>, _, _, _>(|a, b| a + b, 10, x),
1865 15
1866 );
1867 assert_eq!(fold_left::<RcFnBrand, StepWithLoopBrand<()>, _, _, _>(|b, a| b + a, 10, x), 15);
1868 assert_eq!(
1869 fold_map::<RcFnBrand, StepWithLoopBrand<()>, _, _, _>(|a: i32| a.to_string(), x),
1870 "5"
1871 );
1872
1873 let loop_step: Step<i32, i32> = Step::Loop(1);
1874 assert_eq!(
1875 fold_right::<RcFnBrand, StepWithLoopBrand<i32>, _, _, _>(|a, b| a + b, 10, loop_step),
1876 10
1877 );
1878 }
1879
1880 #[test]
1884 fn test_foldable_step_with_done() {
1885 let x = pure::<StepWithDoneBrand<()>, _>(5);
1886 assert_eq!(
1887 fold_right::<RcFnBrand, StepWithDoneBrand<()>, _, _, _>(|a, b| a + b, 10, x),
1888 15
1889 );
1890 assert_eq!(fold_left::<RcFnBrand, StepWithDoneBrand<()>, _, _, _>(|b, a| b + a, 10, x), 15);
1891 assert_eq!(
1892 fold_map::<RcFnBrand, StepWithDoneBrand<()>, _, _, _>(|a: i32| a.to_string(), x),
1893 "5"
1894 );
1895
1896 let done_step: Step<i32, i32> = Step::Done(1);
1897 assert_eq!(
1898 fold_right::<RcFnBrand, StepWithDoneBrand<i32>, _, _, _>(|a, b| a + b, 10, done_step),
1899 10
1900 );
1901 }
1902
1903 #[test]
1909 fn test_traversable_step_with_loop() {
1910 let x = pure::<StepWithLoopBrand<()>, _>(5);
1911 assert_eq!(
1912 traverse::<StepWithLoopBrand<()>, _, _, OptionBrand, _>(|a| Some(a * 2), x),
1913 Some(Step::Done(10))
1914 );
1915
1916 let loop_step: Step<i32, i32> = Step::Loop(1);
1917 assert_eq!(
1918 traverse::<StepWithLoopBrand<i32>, _, _, OptionBrand, _>(|a| Some(a * 2), loop_step),
1919 Some(Step::Loop(1))
1920 );
1921 }
1922
1923 #[test]
1927 fn test_traversable_step_with_done() {
1928 let x = pure::<StepWithDoneBrand<()>, _>(5);
1929 assert_eq!(
1930 traverse::<StepWithDoneBrand<()>, _, _, OptionBrand, _>(|a| Some(a * 2), x),
1931 Some(Step::Loop(10))
1932 );
1933
1934 let done_step: Step<i32, i32> = Step::Done(1);
1935 assert_eq!(
1936 traverse::<StepWithDoneBrand<i32>, _, _, OptionBrand, _>(|a| Some(a * 2), done_step),
1937 Some(Step::Done(1))
1938 );
1939 }
1940
1941 #[test]
1947 fn test_par_foldable_step_with_loop() {
1948 let x = pure::<StepWithLoopBrand<()>, _>(5);
1949 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|a: i32| a.to_string());
1950 assert_eq!(par_fold_map::<ArcFnBrand, StepWithLoopBrand<()>, _, _>(f, x), "5");
1951 }
1952
1953 #[test]
1957 fn test_par_foldable_step_with_done() {
1958 let x = pure::<StepWithDoneBrand<()>, _>(5);
1959 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|a: i32| a.to_string());
1960 assert_eq!(par_fold_map::<ArcFnBrand, StepWithDoneBrand<()>, _, _>(f, x), "5");
1961 }
1962
1963 #[quickcheck]
1967 fn monad_left_identity_step_with_loop(a: i32) -> bool {
1968 let f = |x: i32| pure::<StepWithLoopBrand<i32>, _>(x.wrapping_mul(2));
1969 bind::<StepWithLoopBrand<i32>, _, _, _>(pure::<StepWithLoopBrand<i32>, _>(a), f) == f(a)
1970 }
1971
1972 #[quickcheck]
1974 fn monad_right_identity_step_with_loop(x: Step<i32, i32>) -> bool {
1975 bind::<StepWithLoopBrand<i32>, _, _, _>(x, pure::<StepWithLoopBrand<i32>, _>) == x
1976 }
1977
1978 #[quickcheck]
1980 fn monad_associativity_step_with_loop(x: Step<i32, i32>) -> bool {
1981 let f = |x: i32| pure::<StepWithLoopBrand<i32>, _>(x.wrapping_mul(2));
1982 let g = |x: i32| pure::<StepWithLoopBrand<i32>, _>(x.wrapping_add(1));
1983 bind::<StepWithLoopBrand<i32>, _, _, _>(bind::<StepWithLoopBrand<i32>, _, _, _>(x, f), g)
1984 == bind::<StepWithLoopBrand<i32>, _, _, _>(x, |a| {
1985 bind::<StepWithLoopBrand<i32>, _, _, _>(f(a), g)
1986 })
1987 }
1988
1989 #[quickcheck]
1993 fn monad_left_identity_step_with_done(a: i32) -> bool {
1994 let f = |x: i32| pure::<StepWithDoneBrand<i32>, _>(x.wrapping_mul(2));
1995 bind::<StepWithDoneBrand<i32>, _, _, _>(pure::<StepWithDoneBrand<i32>, _>(a), f) == f(a)
1996 }
1997
1998 #[quickcheck]
2000 fn monad_right_identity_step_with_done(x: Step<i32, i32>) -> bool {
2001 bind::<StepWithDoneBrand<i32>, _, _, _>(x, pure::<StepWithDoneBrand<i32>, _>) == x
2002 }
2003
2004 #[quickcheck]
2006 fn monad_associativity_step_with_done(x: Step<i32, i32>) -> bool {
2007 let f = |x: i32| pure::<StepWithDoneBrand<i32>, _>(x.wrapping_mul(2));
2008 let g = |x: i32| pure::<StepWithDoneBrand<i32>, _>(x.wrapping_add(1));
2009 bind::<StepWithDoneBrand<i32>, _, _, _>(bind::<StepWithDoneBrand<i32>, _, _, _>(x, f), g)
2010 == bind::<StepWithDoneBrand<i32>, _, _, _>(x, |a| {
2011 bind::<StepWithDoneBrand<i32>, _, _, _>(f(a), g)
2012 })
2013 }
2014}