1#[fp_macros::document_module]
6mod inner {
7 #[cfg(feature = "rayon")]
8 use rayon::prelude::*;
9 use {
10 crate::{
11 Apply,
12 brands::{
13 OptionBrand,
14 VecBrand,
15 },
16 classes::{
17 Alt,
18 Applicative,
19 ApplyFirst,
20 ApplySecond,
21 CloneableFn,
22 Compactable,
23 Filterable,
24 Foldable,
25 Functor,
26 Lift,
27 Monoid,
28 ParFoldable,
29 Plus,
30 Pointed,
31 Semiapplicative,
32 Semigroup,
33 Semimonad,
34 SendCloneableFn,
35 Traversable,
36 Witherable,
37 foldable_with_index::FoldableWithIndex,
38 functor_with_index::FunctorWithIndex,
39 traversable_with_index::TraversableWithIndex,
40 },
41 impl_kind,
42 kinds::*,
43 },
44 fp_macros::*,
45 };
46
47 impl_kind! {
48 for VecBrand {
49 type Of<'a, A: 'a>: 'a = Vec<A>;
50 }
51 }
52
53 impl VecBrand {
54 #[document_signature]
58 #[document_type_parameters("The type of the elements in the vector.")]
60 #[document_parameters(
62 "A value to prepend to the vector.",
63 "A vector to prepend the value to."
64 )]
65 #[document_returns(
67 "A new vector consisting of the `head` element prepended to the `tail` vector."
68 )]
69 #[document_examples]
70 pub fn construct<A>(
84 head: A,
85 tail: Vec<A>,
86 ) -> Vec<A>
87 where
88 A: Clone, {
89 [vec![head], tail].concat()
90 }
91
92 #[document_signature]
96 #[document_type_parameters("The type of the elements in the vector.")]
98 #[document_parameters("The vector slice to deconstruct.")]
100 #[document_returns(
102 "An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
103 )]
104 #[document_examples]
106 pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
118 where
119 A: Clone, {
120 match slice {
121 [] => None,
122 [head, tail @ ..] => Some((head.clone(), tail.to_vec())),
123 }
124 }
125 }
126
127 impl Functor for VecBrand {
128 #[document_signature]
132 #[document_type_parameters(
134 "The lifetime of the elements.",
135 "The type of the elements in the vector.",
136 "The type of the elements in the resulting vector."
137 )]
138 #[document_parameters("The function to apply to each element.", "The vector to map over.")]
140 #[document_returns("A new vector containing the results of applying the function.")]
142 #[document_examples]
144 fn map<'a, A: 'a, B: 'a>(
154 func: impl Fn(A) -> B + 'a,
155 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
156 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
157 fa.into_iter().map(func).collect()
158 }
159 }
160
161 impl Lift for VecBrand {
162 #[document_signature]
166 #[document_type_parameters(
168 "The lifetime of the elements.",
169 "The type of the elements in the first vector.",
170 "The type of the elements in the second vector.",
171 "The type of the elements in the resulting vector."
172 )]
173 #[document_parameters(
175 "The binary function to apply.",
176 "The first vector.",
177 "The second vector."
178 )]
179 #[document_returns(
181 "A new vector containing the results of applying the function to all pairs of elements."
182 )]
183 #[document_examples]
184 fn lift2<'a, A, B, C>(
197 func: impl Fn(A, B) -> C + 'a,
198 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
199 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
200 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
201 where
202 A: Clone + 'a,
203 B: Clone + 'a,
204 C: 'a, {
205 fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
206 }
207 }
208
209 impl Pointed for VecBrand {
210 #[document_signature]
214 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
216 #[document_parameters("The value to wrap.")]
218 #[document_returns("A vector containing the single value.")]
220 #[document_examples]
222 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
232 vec![a]
233 }
234 }
235
236 impl ApplyFirst for VecBrand {}
237 impl ApplySecond for VecBrand {}
238
239 impl Semiapplicative for VecBrand {
240 #[document_signature]
244 #[document_type_parameters(
246 "The lifetime of the values.",
247 "The brand of the cloneable function wrapper.",
248 "The type of the input values.",
249 "The type of the output values."
250 )]
251 #[document_parameters(
253 "The vector containing the functions.",
254 "The vector containing the values."
255 )]
256 #[document_returns(
258 "A new vector containing the results of applying each function to each value."
259 )]
260 #[document_examples]
261 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
276 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
277 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
278 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
279 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
280 }
281 }
282
283 impl Semimonad for VecBrand {
284 #[document_signature]
288 #[document_type_parameters(
290 "The lifetime of the elements.",
291 "The type of the elements in the input vector.",
292 "The type of the elements in the output vector."
293 )]
294 #[document_parameters(
296 "The first vector.",
297 "The function to apply to each element, returning a vector."
298 )]
299 #[document_returns("A new vector containing the flattened results.")]
301 #[document_examples]
302 fn bind<'a, A: 'a, B: 'a>(
312 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
313 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
314 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
315 ma.into_iter().flat_map(func).collect()
316 }
317 }
318
319 impl Alt for VecBrand {
320 #[document_signature]
325 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
327 #[document_parameters("The first vector.", "The second vector.")]
329 #[document_returns("The concatenated vector.")]
331 #[document_examples]
332 fn alt<'a, A: 'a>(
345 fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
346 fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
347 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
348 let mut result = fa1;
349 result.extend(fa2);
350 result
351 }
352 }
353
354 impl Plus for VecBrand {
355 #[document_signature]
357 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
359 #[document_returns("An empty vector.")]
361 #[document_examples]
362 fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
373 Vec::new()
374 }
375 }
376
377 impl Foldable for VecBrand {
378 #[document_signature]
382 #[document_type_parameters(
384 "The lifetime of the elements.",
385 "The brand of the cloneable function to use.",
386 "The type of the elements in the vector.",
387 "The type of the accumulator."
388 )]
389 #[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
391 #[document_returns("The final accumulator value.")]
393 #[document_examples]
395 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
405 func: impl Fn(A, B) -> B + 'a,
406 initial: B,
407 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
408 ) -> B
409 where
410 FnBrand: CloneableFn + 'a, {
411 fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
412 }
413
414 #[document_signature]
418 #[document_type_parameters(
420 "The lifetime of the elements.",
421 "The brand of the cloneable function to use.",
422 "The type of the elements in the vector.",
423 "The type of the accumulator."
424 )]
425 #[document_parameters(
427 "The function to apply to the accumulator and each element.",
428 "The initial value of the accumulator.",
429 "The vector to fold."
430 )]
431 #[document_returns("The final accumulator value.")]
433 #[document_examples]
434 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
444 func: impl Fn(B, A) -> B + 'a,
445 initial: B,
446 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
447 ) -> B
448 where
449 FnBrand: CloneableFn + 'a, {
450 fa.into_iter().fold(initial, func)
451 }
452
453 #[document_signature]
457 #[document_type_parameters(
459 "The lifetime of the elements.",
460 "The brand of the cloneable function to use.",
461 "The type of the elements in the vector.",
462 "The type of the monoid."
463 )]
464 #[document_parameters("The mapping function.", "The vector to fold.")]
466 #[document_returns("The combined monoid value.")]
468 #[document_examples]
470 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
483 func: impl Fn(A) -> M + 'a,
484 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
485 ) -> M
486 where
487 M: Monoid + 'a,
488 FnBrand: CloneableFn + 'a, {
489 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
490 }
491 }
492
493 impl Traversable for VecBrand {
494 #[document_signature]
498 #[document_type_parameters(
500 "The lifetime of the elements.",
501 "The type of the elements in the traversable structure.",
502 "The type of the elements in the resulting traversable structure.",
503 "The applicative context."
504 )]
505 #[document_parameters(
507 "The function to apply to each element, returning a value in an applicative context.",
508 "The vector to traverse."
509 )]
510 #[document_returns("The vector wrapped in the applicative context.")]
512 #[document_examples]
513 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
529 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
530 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
531 ) -> 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>)>)
532 where
533 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
534 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
535 let len = ta.len();
536 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
537 F::lift2(
538 |mut v, b| {
539 v.push(b);
540 v
541 },
542 acc,
543 func(x),
544 )
545 })
546 }
547
548 #[document_signature]
552 #[document_type_parameters(
554 "The lifetime of the elements.",
555 "The type of the elements in the traversable structure.",
556 "The applicative context."
557 )]
558 #[document_parameters("The vector containing the applicative values.")]
560 #[document_returns("The vector wrapped in the applicative context.")]
562 #[document_examples]
564 fn sequence<'a, A: 'a + Clone, F: Applicative>(
577 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>)>)
578 ) -> 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>)>)
579 where
580 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
581 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
582 let len = ta.len();
583 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
584 F::lift2(
585 |mut v, a| {
586 v.push(a);
587 v
588 },
589 acc,
590 x,
591 )
592 })
593 }
594 }
595
596 impl FunctorWithIndex<usize> for VecBrand {
597 #[document_signature]
599 #[document_type_parameters(
600 "The lifetime of the elements.",
601 "The type of the elements in the vector.",
602 "The type of the elements in the resulting vector."
603 )]
604 #[document_parameters(
605 "The function to apply to each element and its index.",
606 "The vector to map over."
607 )]
608 #[document_returns("A new vector containing the results of applying the function.")]
609 #[document_examples]
610 fn map_with_index<'a, A: 'a, B: 'a>(
624 f: impl Fn(usize, A) -> B + 'a,
625 fa: Vec<A>,
626 ) -> Vec<B> {
627 fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
628 }
629 }
630
631 impl FoldableWithIndex<usize> for VecBrand {
632 #[document_signature]
634 #[document_type_parameters(
635 "The lifetime of the elements.",
636 "The type of the elements in the vector.",
637 "The monoid type."
638 )]
639 #[document_parameters(
640 "The function to apply to each element and its index.",
641 "The vector to fold."
642 )]
643 #[document_returns("The combined monoid value.")]
644 #[document_examples]
645 fn fold_map_with_index<'a, A: 'a, R: Monoid>(
660 f: impl Fn(usize, A) -> R + 'a,
661 fa: Vec<A>,
662 ) -> R {
663 fa.into_iter()
664 .enumerate()
665 .map(|(i, a)| f(i, a))
666 .fold(R::empty(), |acc, x| R::append(acc, x))
667 }
668 }
669
670 impl TraversableWithIndex<usize> for VecBrand {
671 #[document_signature]
673 #[document_type_parameters(
674 "The lifetime of the elements.",
675 "The type of the elements in the vector.",
676 "The type of the elements in the resulting vector.",
677 "The applicative context."
678 )]
679 #[document_parameters(
680 "The function to apply to each element and its index, returning a value in an applicative context.",
681 "The vector to traverse."
682 )]
683 #[document_returns("The vector wrapped in the applicative context.")]
684 #[document_examples]
685 fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
703 f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
704 ta: Vec<A>,
705 ) -> M::Of<'a, Vec<B>> {
706 let len = ta.len();
707 ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
708 M::lift2(
709 |mut v, b| {
710 v.push(b);
711 v
712 },
713 acc,
714 f(i, x),
715 )
716 })
717 }
718 }
719
720 #[document_type_parameters("The type of the elements in the vector.")]
721 impl<A: Clone> Semigroup for Vec<A> {
722 #[document_signature]
726 #[document_parameters("The first vector.", "The second vector.")]
728 #[document_returns("The concatenated vector.")]
730 #[document_examples]
732 fn append(
739 a: Self,
740 b: Self,
741 ) -> Self {
742 [a, b].concat()
743 }
744 }
745
746 #[document_type_parameters("The type of the elements in the vector.")]
747 impl<A: Clone> Monoid for Vec<A> {
748 #[document_signature]
752 #[document_returns("An empty vector.")]
754 #[document_examples]
756 fn empty() -> Self {
763 Vec::new()
764 }
765 }
766
767 impl ParFoldable for VecBrand {
768 #[document_signature]
774 #[document_type_parameters(
776 "The lifetime of the elements.",
777 "The brand of the cloneable function wrapper.",
778 "The element type.",
779 "The monoid type."
780 )]
781 #[document_parameters(
783 "The thread-safe function to map each element to a monoid.",
784 "The vector to fold."
785 )]
786 #[document_returns("The combined monoid value.")]
788 #[document_examples]
789 fn par_fold_map<'a, FnBrand, A, M>(
801 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
802 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
803 ) -> M
804 where
805 FnBrand: 'a + SendCloneableFn,
806 A: 'a + Clone + Send + Sync,
807 M: Monoid + Send + Sync + 'a, {
808 #[cfg(feature = "rayon")]
809 {
810 #[allow(clippy::redundant_closure)] fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
812 }
813 #[cfg(not(feature = "rayon"))]
814 {
815 #[allow(clippy::redundant_closure)] fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
817 }
818 }
819 }
820
821 impl Compactable for VecBrand {
822 #[document_signature]
826 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
828 #[document_parameters("The vector of options.")]
830 #[document_returns("The flattened vector.")]
832 #[document_examples]
834 fn compact<'a, A: 'a>(
846 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
847 'a,
848 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
849 >)
850 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
851 fa.into_iter().flatten().collect()
852 }
853
854 #[document_signature]
858 #[document_type_parameters(
860 "The lifetime of the elements.",
861 "The type of the error value.",
862 "The type of the success value."
863 )]
864 #[document_parameters("The vector of results.")]
866 #[document_returns("A pair of vectors.")]
868 #[document_examples]
870 fn separate<'a, E: 'a, O: 'a>(
883 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
884 ) -> (
885 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
886 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
887 ) {
888 let mut oks = Vec::new();
889 let mut errs = Vec::new();
890 for result in fa {
891 match result {
892 Ok(o) => oks.push(o),
893 Err(e) => errs.push(e),
894 }
895 }
896 (errs, oks)
897 }
898 }
899
900 impl Filterable for VecBrand {
901 #[document_signature]
905 #[document_type_parameters(
907 "The lifetime of the elements.",
908 "The type of the input value.",
909 "The type of the error value.",
910 "The type of the success value."
911 )]
912 #[document_parameters("The function to apply.", "The vector to partition.")]
914 #[document_returns("A pair of vectors.")]
916 #[document_examples]
918 fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
932 func: impl Fn(A) -> Result<O, E> + 'a,
933 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
934 ) -> (
935 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
936 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
937 ) {
938 let mut oks = Vec::new();
939 let mut errs = Vec::new();
940 for a in fa {
941 match func(a) {
942 Ok(o) => oks.push(o),
943 Err(e) => errs.push(e),
944 }
945 }
946 (errs, oks)
947 }
948
949 #[document_signature]
953 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
955 #[document_parameters("The predicate.", "The vector to partition.")]
957 #[document_returns("A pair of vectors.")]
959 #[document_examples]
961 fn partition<'a, A: 'a + Clone>(
974 func: impl Fn(A) -> bool + 'a,
975 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
976 ) -> (
977 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
978 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
979 ) {
980 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
981 fa.into_iter().partition(|a| func(a.clone()));
982 (not_satisfied, satisfied)
983 }
984
985 #[document_signature]
989 #[document_type_parameters(
991 "The lifetime of the elements.",
992 "The type of the input value.",
993 "The type of the result of applying the function."
994 )]
995 #[document_parameters("The function to apply.", "The vector to filter and map.")]
997 #[document_returns("The filtered and mapped vector.")]
999 #[document_examples]
1001 fn filter_map<'a, A: 'a, B: 'a>(
1013 func: impl Fn(A) -> Option<B> + 'a,
1014 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1015 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1016 fa.into_iter().filter_map(func).collect()
1017 }
1018
1019 #[document_signature]
1023 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1025 #[document_parameters("The predicate.", "The vector to filter.")]
1027 #[document_returns("The filtered vector.")]
1029 #[document_examples]
1031 fn filter<'a, A: 'a + Clone>(
1043 func: impl Fn(A) -> bool + 'a,
1044 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1045 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1046 fa.into_iter().filter(|a| func(a.clone())).collect()
1047 }
1048 }
1049
1050 impl Witherable for VecBrand {
1051 #[document_signature]
1055 #[document_type_parameters(
1057 "The lifetime of the elements.",
1058 "The applicative context.",
1059 "The type of the input value.",
1060 "The type of the error value.",
1061 "The type of the success value."
1062 )]
1063 #[document_parameters("The function to apply.", "The vector to partition.")]
1065 #[document_returns("The partitioned vector wrapped in the applicative context.")]
1067 #[document_examples]
1069 fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1084 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1085 + 'a,
1086 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1087 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1088 'a,
1089 (
1090 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1091 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1092 ),
1093 >)
1094 where
1095 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1096 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1097 ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
1098 M::lift2(
1099 |mut pair, res| {
1100 match res {
1101 Ok(o) => pair.1.push(o),
1102 Err(e) => pair.0.push(e),
1103 }
1104 pair
1105 },
1106 acc,
1107 func(x),
1108 )
1109 })
1110 }
1111
1112 #[document_signature]
1116 #[document_type_parameters(
1118 "The lifetime of the values.",
1119 "The applicative context.",
1120 "The type of the elements in the input structure.",
1121 "The type of the result of applying the function."
1122 )]
1123 #[document_parameters(
1125 "The function to apply to each element, returning an `Option` in an applicative context.",
1126 "The vector to filter and map."
1127 )]
1128 #[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
1130 #[document_examples]
1131 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1149 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1150 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1151 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1152 'a,
1153 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1154 >)
1155 where
1156 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1157 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1158 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1159 M::lift2(
1160 |mut v, opt_b| {
1161 if let Some(b) = opt_b {
1162 v.push(b);
1163 }
1164 v
1165 },
1166 acc,
1167 func(x),
1168 )
1169 })
1170 }
1171 }
1172}
1173
1174#[cfg(test)]
1175mod tests {
1176
1177 use {
1178 crate::{
1179 brands::*,
1180 classes::CloneableFn,
1181 functions::*,
1182 },
1183 quickcheck_macros::quickcheck,
1184 };
1185
1186 #[quickcheck]
1190 fn functor_identity(x: Vec<i32>) -> bool {
1191 map::<VecBrand, _, _>(identity, x.clone()) == x
1192 }
1193
1194 #[quickcheck]
1196 fn functor_composition(x: Vec<i32>) -> bool {
1197 let f = |x: i32| x.wrapping_add(1);
1198 let g = |x: i32| x.wrapping_mul(2);
1199 map::<VecBrand, _, _>(compose(f, g), x.clone())
1200 == map::<VecBrand, _, _>(f, map::<VecBrand, _, _>(g, x))
1201 }
1202
1203 #[quickcheck]
1207 fn applicative_identity(v: Vec<i32>) -> bool {
1208 apply::<RcFnBrand, VecBrand, _, _>(
1209 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1210 v.clone(),
1211 ) == v
1212 }
1213
1214 #[quickcheck]
1216 fn applicative_homomorphism(x: i32) -> bool {
1217 let f = |x: i32| x.wrapping_mul(2);
1218 apply::<RcFnBrand, VecBrand, _, _>(
1219 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1220 pure::<VecBrand, _>(x),
1221 ) == pure::<VecBrand, _>(f(x))
1222 }
1223
1224 #[quickcheck]
1226 fn applicative_composition(
1227 w: Vec<i32>,
1228 u_seeds: Vec<i32>,
1229 v_seeds: Vec<i32>,
1230 ) -> bool {
1231 let u_fns: Vec<_> = u_seeds
1232 .iter()
1233 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1234 .collect();
1235 let v_fns: Vec<_> = v_seeds
1236 .iter()
1237 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1238 .collect();
1239
1240 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1242 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1243
1244 let uv_fns: Vec<_> = u_fns
1248 .iter()
1249 .flat_map(|uf| {
1250 v_fns.iter().map(move |vf| {
1251 let uf = uf.clone();
1252 let vf = vf.clone();
1253 <RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1254 })
1255 })
1256 .collect();
1257
1258 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1259
1260 lhs == rhs
1261 }
1262
1263 #[quickcheck]
1265 fn applicative_interchange(y: i32) -> bool {
1266 let f = |x: i32| x.wrapping_mul(2);
1268 let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1269
1270 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1271
1272 let rhs_fn =
1273 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1274 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1275
1276 lhs == rhs
1277 }
1278
1279 #[quickcheck]
1283 fn semigroup_associativity(
1284 a: Vec<i32>,
1285 b: Vec<i32>,
1286 c: Vec<i32>,
1287 ) -> bool {
1288 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1289 }
1290
1291 #[quickcheck]
1295 fn monoid_left_identity(a: Vec<i32>) -> bool {
1296 append(empty::<Vec<i32>>(), a.clone()) == a
1297 }
1298
1299 #[quickcheck]
1301 fn monoid_right_identity(a: Vec<i32>) -> bool {
1302 append(a.clone(), empty::<Vec<i32>>()) == a
1303 }
1304
1305 #[quickcheck]
1309 fn monad_left_identity(a: i32) -> bool {
1310 let f = |x: i32| vec![x.wrapping_mul(2)];
1311 bind::<VecBrand, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1312 }
1313
1314 #[quickcheck]
1316 fn monad_right_identity(m: Vec<i32>) -> bool {
1317 bind::<VecBrand, _, _>(m.clone(), pure::<VecBrand, _>) == m
1318 }
1319
1320 #[quickcheck]
1322 fn monad_associativity(m: Vec<i32>) -> bool {
1323 let f = |x: i32| vec![x.wrapping_mul(2)];
1324 let g = |x: i32| vec![x.wrapping_add(1)];
1325 bind::<VecBrand, _, _>(bind::<VecBrand, _, _>(m.clone(), f), g)
1326 == bind::<VecBrand, _, _>(m, |x| bind::<VecBrand, _, _>(f(x), g))
1327 }
1328
1329 #[test]
1333 fn map_empty() {
1334 assert_eq!(map::<VecBrand, _, _>(|x: i32| x + 1, vec![] as Vec<i32>), vec![] as Vec<i32>);
1335 }
1336
1337 #[test]
1339 fn bind_empty() {
1340 assert_eq!(
1341 bind::<VecBrand, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1342 vec![] as Vec<i32>
1343 );
1344 }
1345
1346 #[test]
1348 fn bind_returning_empty() {
1349 assert_eq!(
1350 bind::<VecBrand, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1351 vec![] as Vec<i32>
1352 );
1353 }
1354
1355 #[test]
1357 fn fold_right_empty() {
1358 assert_eq!(
1359 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _>(
1360 |x: i32, acc| x + acc,
1361 0,
1362 vec![]
1363 ),
1364 0
1365 );
1366 }
1367
1368 #[test]
1370 fn fold_left_empty() {
1371 assert_eq!(
1372 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _>(
1373 |acc, x: i32| acc + x,
1374 0,
1375 vec![]
1376 ),
1377 0
1378 );
1379 }
1380
1381 #[test]
1383 fn traverse_empty() {
1384 use crate::brands::OptionBrand;
1385 assert_eq!(
1386 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1387 |x: i32| Some(x + 1),
1388 vec![]
1389 ),
1390 Some(vec![])
1391 );
1392 }
1393
1394 #[test]
1396 fn traverse_returning_empty() {
1397 use crate::brands::OptionBrand;
1398 assert_eq!(
1399 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1400 |_: i32| None::<i32>,
1401 vec![1, 2, 3]
1402 ),
1403 None
1404 );
1405 }
1406
1407 #[test]
1409 fn construct_empty_tail() {
1410 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1411 }
1412
1413 #[test]
1415 fn deconstruct_empty() {
1416 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1417 }
1418
1419 #[test]
1423 fn par_fold_map_empty() {
1424 let v: Vec<i32> = vec![];
1425 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1426 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1427 }
1428
1429 #[test]
1431 fn par_fold_map_single() {
1432 let v = vec![1];
1433 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1434 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1435 }
1436
1437 #[test]
1439 fn par_fold_map_multiple() {
1440 let v = vec![1, 2, 3];
1441 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1442 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1443 }
1444
1445 #[test]
1447 fn par_fold_right_multiple() {
1448 let v = vec![1, 2, 3];
1449 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1450 assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1451 }
1452
1453 #[quickcheck]
1457 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1458 filter_map::<VecBrand, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1459 }
1460
1461 #[quickcheck]
1463 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1464 filter_map::<VecBrand, _, _>(Some, x.clone()) == x
1465 }
1466
1467 #[quickcheck]
1469 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1470 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1471 let l = |i: i32| if i > 5 { Some(i) } else { None };
1472 let composed = |i| bind::<OptionBrand, _, _>(r(i), l);
1473
1474 filter_map::<VecBrand, _, _>(composed, x.clone())
1475 == filter_map::<VecBrand, _, _>(l, filter_map::<VecBrand, _, _>(r, x))
1476 }
1477
1478 #[quickcheck]
1480 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1481 let p = |i: i32| i % 2 == 0;
1482 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1483
1484 filter::<VecBrand, _>(p, x.clone()) == filter_map::<VecBrand, _, _>(maybe_bool, x)
1485 }
1486
1487 #[quickcheck]
1489 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1490 partition_map::<VecBrand, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1491 }
1492
1493 #[quickcheck]
1495 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1496 let (_, oks) = partition_map::<VecBrand, _, _, _>(Ok::<_, i32>, x.clone());
1497 oks == x
1498 }
1499
1500 #[quickcheck]
1502 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1503 let (errs, _) = partition_map::<VecBrand, _, _, _>(Err::<i32, _>, x.clone());
1504 errs == x
1505 }
1506
1507 #[quickcheck]
1509 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1510 let p = |i: i32| i % 2 == 0;
1511 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1512
1513 let (not_satisfied, satisfied) = partition::<VecBrand, _>(p, x.clone());
1514 let (errs, oks) = partition_map::<VecBrand, _, _, _>(either_bool, x);
1515
1516 satisfied == oks && not_satisfied == errs
1517 }
1518
1519 #[quickcheck]
1523 fn witherable_identity(x: Vec<i32>) -> bool {
1524 wither::<VecBrand, OptionBrand, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1525 }
1526
1527 #[quickcheck]
1529 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1530 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1531
1532 let lhs = wilt::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1533 let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
1534 separate::<VecBrand, _, _>,
1535 traverse::<VecBrand, _, _, OptionBrand>(p, x),
1536 );
1537
1538 lhs == rhs
1539 }
1540
1541 #[quickcheck]
1543 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1544 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1545
1546 let lhs = wither::<VecBrand, OptionBrand, _, _>(p, x.clone());
1547 let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
1548 compact::<VecBrand, _>,
1549 traverse::<VecBrand, _, _, OptionBrand>(p, x),
1550 );
1551
1552 lhs == rhs
1553 }
1554
1555 #[quickcheck]
1559 fn alt_associativity(
1560 x: Vec<i32>,
1561 y: Vec<i32>,
1562 z: Vec<i32>,
1563 ) -> bool {
1564 alt::<VecBrand, _>(alt::<VecBrand, _>(x.clone(), y.clone()), z.clone())
1565 == alt::<VecBrand, _>(x, alt::<VecBrand, _>(y, z))
1566 }
1567
1568 #[quickcheck]
1570 fn alt_distributivity(
1571 x: Vec<i32>,
1572 y: Vec<i32>,
1573 ) -> bool {
1574 let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
1575 map::<VecBrand, _, _>(f, alt::<VecBrand, _>(x.clone(), y.clone()))
1576 == alt::<VecBrand, _>(map::<VecBrand, _, _>(f, x), map::<VecBrand, _, _>(f, y))
1577 }
1578
1579 #[quickcheck]
1583 fn plus_left_identity(x: Vec<i32>) -> bool {
1584 alt::<VecBrand, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
1585 }
1586
1587 #[quickcheck]
1589 fn plus_right_identity(x: Vec<i32>) -> bool {
1590 alt::<VecBrand, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
1591 }
1592
1593 #[test]
1595 fn plus_annihilation() {
1596 let f = |i: i32| i.wrapping_mul(2);
1597 assert_eq!(
1598 map::<VecBrand, _, _>(f, plus_empty::<VecBrand, i32>()),
1599 plus_empty::<VecBrand, i32>(),
1600 );
1601 }
1602
1603 #[quickcheck]
1607 fn compactable_functor_identity(fa: Vec<i32>) -> bool {
1608 compact::<VecBrand, _>(map::<VecBrand, _, _>(Some, fa.clone())) == fa
1609 }
1610
1611 #[test]
1613 fn compactable_plus_annihilation_empty() {
1614 assert_eq!(
1615 compact::<VecBrand, _>(plus_empty::<VecBrand, Option<i32>>()),
1616 plus_empty::<VecBrand, i32>(),
1617 );
1618 }
1619
1620 #[quickcheck]
1622 fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
1623 compact::<VecBrand, _>(map::<VecBrand, _, _>(|_: i32| None::<i32>, xs))
1624 == plus_empty::<VecBrand, i32>()
1625 }
1626
1627 #[test]
1631 fn compact_empty() {
1632 assert_eq!(compact::<VecBrand, i32>(vec![] as Vec<Option<i32>>), vec![] as Vec<i32>);
1633 }
1634
1635 #[test]
1637 fn compact_with_none() {
1638 assert_eq!(compact::<VecBrand, i32>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1639 }
1640
1641 #[test]
1643 fn separate_empty() {
1644 let (errs, oks) = separate::<VecBrand, i32, i32>(vec![] as Vec<Result<i32, i32>>);
1645 assert_eq!(oks, vec![] as Vec<i32>);
1646 assert_eq!(errs, vec![] as Vec<i32>);
1647 }
1648
1649 #[test]
1651 fn separate_mixed() {
1652 let (errs, oks) = separate::<VecBrand, i32, i32>(vec![Ok(1), Err(2), Ok(3)]);
1653 assert_eq!(oks, vec![1, 3]);
1654 assert_eq!(errs, vec![2]);
1655 }
1656
1657 #[test]
1659 fn partition_map_empty() {
1660 let (errs, oks) =
1661 partition_map::<VecBrand, i32, i32, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1662 assert_eq!(oks, vec![] as Vec<i32>);
1663 assert_eq!(errs, vec![] as Vec<i32>);
1664 }
1665
1666 #[test]
1668 fn partition_empty() {
1669 let (not_satisfied, satisfied) = partition::<VecBrand, i32>(|x: i32| x > 0, vec![]);
1670 assert_eq!(satisfied, vec![] as Vec<i32>);
1671 assert_eq!(not_satisfied, vec![] as Vec<i32>);
1672 }
1673
1674 #[test]
1676 fn filter_map_empty() {
1677 assert_eq!(filter_map::<VecBrand, i32, _>(|x: i32| Some(x), vec![]), vec![] as Vec<i32>);
1678 }
1679
1680 #[test]
1682 fn filter_empty() {
1683 assert_eq!(filter::<VecBrand, i32>(|x: i32| x > 0, vec![]), vec![] as Vec<i32>);
1684 }
1685
1686 #[test]
1688 fn wilt_empty() {
1689 let res = wilt::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1690 assert_eq!(res, Some((vec![], vec![])));
1691 }
1692
1693 #[test]
1695 fn wither_empty() {
1696 let res = wither::<VecBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), vec![]);
1697 assert_eq!(res, Some(vec![]));
1698 }
1699
1700 #[test]
1704 fn test_large_vector_par_fold_map() {
1705 use crate::types::Additive;
1706
1707 let xs: Vec<i32> = (0 .. 100000).collect();
1708 let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1709 let res = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1710 assert_eq!(res, Additive(4999950000));
1711 }
1712
1713 #[quickcheck]
1715 fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
1716 use crate::types::Additive;
1717
1718 let f_seq = |x: i32| Additive(x as i64);
1719 let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1720
1721 let seq_res =
1722 crate::classes::foldable::fold_map::<ArcFnBrand, VecBrand, _, _>(f_seq, xs.clone());
1723 let par_res = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1724
1725 seq_res == par_res
1726 }
1727
1728 #[quickcheck]
1730 fn prop_par_fold_right_equals_fold_right(xs: Vec<i32>) -> bool {
1731 let f_seq = |a: i32, b: i32| a.wrapping_add(b);
1732 let f_par =
1733 send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a.wrapping_add(b));
1734 let init = 0;
1735
1736 let seq_res = crate::classes::foldable::fold_right::<ArcFnBrand, VecBrand, _, _>(
1737 f_seq,
1738 init,
1739 xs.clone(),
1740 );
1741 let par_res = par_fold_right::<ArcFnBrand, VecBrand, _, _>(f_par, init, xs);
1742
1743 seq_res == par_res
1744 }
1745
1746 #[quickcheck]
1748 fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
1749 use crate::types::Additive;
1750
1751 if !xs.is_empty() {
1752 return true;
1753 }
1754
1755 let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1756 let par_res = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1757
1758 par_res == empty::<Additive<i64>>()
1759 }
1760
1761 #[quickcheck]
1763 fn prop_par_fold_map_deterministic(xs: Vec<i32>) -> bool {
1764 use crate::types::Additive;
1765
1766 let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1767
1768 let res1 = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par.clone(), xs.clone());
1769 let res2 = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1770 res1 == res2
1771 }
1772}