1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::{
11 OptionBrand,
12 VecBrand,
13 },
14 classes::{
15 Alt,
16 Applicative,
17 ApplyFirst,
18 ApplySecond,
19 CloneableFn,
20 Compactable,
21 Filterable,
22 Foldable,
23 Functor,
24 Lift,
25 Monoid,
26 ParCompactable,
27 ParFilterable,
28 ParFoldable,
29 ParFunctor,
30 Plus,
31 Pointed,
32 Semiapplicative,
33 Semigroup,
34 Semimonad,
35 Traversable,
36 Witherable,
37 foldable_with_index::FoldableWithIndex,
38 functor_with_index::FunctorWithIndex,
39 par_foldable_with_index::ParFoldableWithIndex,
40 par_functor_with_index::ParFunctorWithIndex,
41 traversable_with_index::TraversableWithIndex,
42 with_index::WithIndex,
43 },
44 impl_kind,
45 kinds::*,
46 },
47 fp_macros::*,
48 };
49
50 impl_kind! {
51 for VecBrand {
52 type Of<'a, A: 'a>: 'a = Vec<A>;
53 }
54 }
55
56 impl VecBrand {
57 #[document_signature]
61 #[document_type_parameters("The type of the elements in the vector.")]
63 #[document_parameters(
65 "A value to prepend to the vector.",
66 "A vector to prepend the value to."
67 )]
68 #[document_returns(
70 "A new vector consisting of the `head` element prepended to the `tail` vector."
71 )]
72 #[document_examples]
73 pub fn construct<A>(
87 head: A,
88 tail: Vec<A>,
89 ) -> Vec<A>
90 where
91 A: Clone, {
92 [vec![head], tail].concat()
93 }
94
95 #[document_signature]
99 #[document_type_parameters("The type of the elements in the vector.")]
101 #[document_parameters("The vector slice to deconstruct.")]
103 #[document_returns(
105 "An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
106 )]
107 #[document_examples]
109 pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
121 where
122 A: Clone, {
123 match slice {
124 [] => None,
125 [head, tail @ ..] => Some((head.clone(), tail.to_vec())),
126 }
127 }
128 }
129
130 impl Functor for VecBrand {
131 #[document_signature]
135 #[document_type_parameters(
137 "The lifetime of the elements.",
138 "The type of the elements in the vector.",
139 "The type of the elements in the resulting vector."
140 )]
141 #[document_parameters("The function to apply to each element.", "The vector to map over.")]
143 #[document_returns("A new vector containing the results of applying the function.")]
145 #[document_examples]
147 fn map<'a, A: 'a, B: 'a>(
157 func: impl Fn(A) -> B + 'a,
158 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
159 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
160 fa.into_iter().map(func).collect()
161 }
162 }
163
164 impl Lift for VecBrand {
165 #[document_signature]
169 #[document_type_parameters(
171 "The lifetime of the elements.",
172 "The type of the elements in the first vector.",
173 "The type of the elements in the second vector.",
174 "The type of the elements in the resulting vector."
175 )]
176 #[document_parameters(
178 "The binary function to apply.",
179 "The first vector.",
180 "The second vector."
181 )]
182 #[document_returns(
184 "A new vector containing the results of applying the function to all pairs of elements."
185 )]
186 #[document_examples]
187 fn lift2<'a, A, B, C>(
200 func: impl Fn(A, B) -> C + 'a,
201 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
202 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
203 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
204 where
205 A: Clone + 'a,
206 B: Clone + 'a,
207 C: 'a, {
208 fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
209 }
210 }
211
212 impl Pointed for VecBrand {
213 #[document_signature]
217 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
219 #[document_parameters("The value to wrap.")]
221 #[document_returns("A vector containing the single value.")]
223 #[document_examples]
225 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
235 vec![a]
236 }
237 }
238
239 impl ApplyFirst for VecBrand {}
240 impl ApplySecond for VecBrand {}
241
242 impl Semiapplicative for VecBrand {
243 #[document_signature]
247 #[document_type_parameters(
249 "The lifetime of the values.",
250 "The brand of the cloneable function wrapper.",
251 "The type of the input values.",
252 "The type of the output values."
253 )]
254 #[document_parameters(
256 "The vector containing the functions.",
257 "The vector containing the values."
258 )]
259 #[document_returns(
261 "A new vector containing the results of applying each function to each value."
262 )]
263 #[document_examples]
264 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
279 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
280 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
281 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
282 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
283 }
284 }
285
286 impl Semimonad for VecBrand {
287 #[document_signature]
291 #[document_type_parameters(
293 "The lifetime of the elements.",
294 "The type of the elements in the input vector.",
295 "The type of the elements in the output vector."
296 )]
297 #[document_parameters(
299 "The first vector.",
300 "The function to apply to each element, returning a vector."
301 )]
302 #[document_returns("A new vector containing the flattened results.")]
304 #[document_examples]
305 fn bind<'a, A: 'a, B: 'a>(
315 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
316 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
317 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
318 ma.into_iter().flat_map(func).collect()
319 }
320 }
321
322 impl Alt for VecBrand {
323 #[document_signature]
328 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
330 #[document_parameters("The first vector.", "The second vector.")]
332 #[document_returns("The concatenated vector.")]
334 #[document_examples]
335 fn alt<'a, A: 'a>(
348 fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
349 fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
350 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
351 let mut result = fa1;
352 result.extend(fa2);
353 result
354 }
355 }
356
357 impl Plus for VecBrand {
358 #[document_signature]
360 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
362 #[document_returns("An empty vector.")]
364 #[document_examples]
365 fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
376 Vec::new()
377 }
378 }
379
380 impl Foldable for VecBrand {
381 #[document_signature]
385 #[document_type_parameters(
387 "The lifetime of the elements.",
388 "The brand of the cloneable function to use.",
389 "The type of the elements in the vector.",
390 "The type of the accumulator."
391 )]
392 #[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
394 #[document_returns("The final accumulator value.")]
396 #[document_examples]
398 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
408 func: impl Fn(A, B) -> B + 'a,
409 initial: B,
410 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
411 ) -> B
412 where
413 FnBrand: CloneableFn + 'a, {
414 fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
415 }
416
417 #[document_signature]
421 #[document_type_parameters(
423 "The lifetime of the elements.",
424 "The brand of the cloneable function to use.",
425 "The type of the elements in the vector.",
426 "The type of the accumulator."
427 )]
428 #[document_parameters(
430 "The function to apply to the accumulator and each element.",
431 "The initial value of the accumulator.",
432 "The vector to fold."
433 )]
434 #[document_returns("The final accumulator value.")]
436 #[document_examples]
437 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
447 func: impl Fn(B, A) -> B + 'a,
448 initial: B,
449 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
450 ) -> B
451 where
452 FnBrand: CloneableFn + 'a, {
453 fa.into_iter().fold(initial, func)
454 }
455
456 #[document_signature]
460 #[document_type_parameters(
462 "The lifetime of the elements.",
463 "The brand of the cloneable function to use.",
464 "The type of the elements in the vector.",
465 "The type of the monoid."
466 )]
467 #[document_parameters("The mapping function.", "The vector to fold.")]
469 #[document_returns("The combined monoid value.")]
471 #[document_examples]
473 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
486 func: impl Fn(A) -> M + 'a,
487 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
488 ) -> M
489 where
490 M: Monoid + 'a,
491 FnBrand: CloneableFn + 'a, {
492 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
493 }
494 }
495
496 impl Traversable for VecBrand {
497 #[document_signature]
501 #[document_type_parameters(
503 "The lifetime of the elements.",
504 "The type of the elements in the traversable structure.",
505 "The type of the elements in the resulting traversable structure.",
506 "The applicative context."
507 )]
508 #[document_parameters(
510 "The function to apply to each element, returning a value in an applicative context.",
511 "The vector to traverse."
512 )]
513 #[document_returns("The vector wrapped in the applicative context.")]
515 #[document_examples]
516 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
532 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
533 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
534 ) -> 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>)>)
535 where
536 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
537 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
538 let len = ta.len();
539 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
540 F::lift2(
541 |mut v, b| {
542 v.push(b);
543 v
544 },
545 acc,
546 func(x),
547 )
548 })
549 }
550
551 #[document_signature]
555 #[document_type_parameters(
557 "The lifetime of the elements.",
558 "The type of the elements in the traversable structure.",
559 "The applicative context."
560 )]
561 #[document_parameters("The vector containing the applicative values.")]
563 #[document_returns("The vector wrapped in the applicative context.")]
565 #[document_examples]
567 fn sequence<'a, A: 'a + Clone, F: Applicative>(
580 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>)>)
581 ) -> 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>)>)
582 where
583 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
584 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
585 let len = ta.len();
586 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
587 F::lift2(
588 |mut v, a| {
589 v.push(a);
590 v
591 },
592 acc,
593 x,
594 )
595 })
596 }
597 }
598
599 impl WithIndex for VecBrand {
600 type Index = usize;
601 }
602
603 impl FunctorWithIndex for VecBrand {
604 #[document_signature]
606 #[document_type_parameters(
607 "The lifetime of the elements.",
608 "The type of the elements in the vector.",
609 "The type of the elements in the resulting vector."
610 )]
611 #[document_parameters(
612 "The function to apply to each element and its index.",
613 "The vector to map over."
614 )]
615 #[document_returns("A new vector containing the results of applying the function.")]
616 #[document_examples]
617 fn map_with_index<'a, A: 'a, B: 'a>(
631 f: impl Fn(usize, A) -> B + 'a,
632 fa: Vec<A>,
633 ) -> Vec<B> {
634 fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
635 }
636 }
637
638 impl FoldableWithIndex for VecBrand {
639 #[document_signature]
641 #[document_type_parameters(
642 "The lifetime of the elements.",
643 "The type of the elements in the vector.",
644 "The monoid type."
645 )]
646 #[document_parameters(
647 "The function to apply to each element and its index.",
648 "The vector to fold."
649 )]
650 #[document_returns("The combined monoid value.")]
651 #[document_examples]
652 fn fold_map_with_index<'a, A: 'a, R: Monoid>(
664 f: impl Fn(usize, A) -> R + 'a,
665 fa: Vec<A>,
666 ) -> R {
667 fa.into_iter()
668 .enumerate()
669 .map(|(i, a)| f(i, a))
670 .fold(R::empty(), |acc, x| R::append(acc, x))
671 }
672 }
673
674 impl TraversableWithIndex for VecBrand {
675 #[document_signature]
677 #[document_type_parameters(
678 "The lifetime of the elements.",
679 "The type of the elements in the vector.",
680 "The type of the elements in the resulting vector.",
681 "The applicative context."
682 )]
683 #[document_parameters(
684 "The function to apply to each element and its index, returning a value in an applicative context.",
685 "The vector to traverse."
686 )]
687 #[document_returns("The vector wrapped in the applicative context.")]
688 #[document_examples]
689 fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
707 f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
708 ta: Vec<A>,
709 ) -> M::Of<'a, Vec<B>> {
710 let len = ta.len();
711 ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
712 M::lift2(
713 |mut v, b| {
714 v.push(b);
715 v
716 },
717 acc,
718 f(i, x),
719 )
720 })
721 }
722 }
723
724 #[document_type_parameters("The type of the elements in the vector.")]
725 impl<A: Clone> Semigroup for Vec<A> {
726 #[document_signature]
730 #[document_parameters("The first vector.", "The second vector.")]
732 #[document_returns("The concatenated vector.")]
734 #[document_examples]
736 fn append(
743 a: Self,
744 b: Self,
745 ) -> Self {
746 [a, b].concat()
747 }
748 }
749
750 #[document_type_parameters("The type of the elements in the vector.")]
751 impl<A: Clone> Monoid for Vec<A> {
752 #[document_signature]
756 #[document_returns("An empty vector.")]
758 #[document_examples]
760 fn empty() -> Self {
767 Vec::new()
768 }
769 }
770
771 impl VecBrand {
772 #[document_signature]
777 #[document_type_parameters(
779 "The lifetime of the elements.",
780 "The input element type.",
781 "The output element type."
782 )]
783 #[document_parameters(
785 "The function to apply to each element. Must be `Send + Sync`.",
786 "The vector to map over."
787 )]
788 #[document_returns("A new vector containing the mapped elements.")]
790 #[document_examples]
792 pub fn par_map<'a, A: 'a + Send, B: 'a + Send>(
800 f: impl Fn(A) -> B + Send + Sync + 'a,
801 fa: Vec<A>,
802 ) -> Vec<B> {
803 #[cfg(feature = "rayon")]
804 {
805 use rayon::prelude::*;
806 fa.into_par_iter().map(f).collect()
807 }
808 #[cfg(not(feature = "rayon"))]
809 fa.into_iter().map(f).collect()
810 }
811
812 #[document_signature]
817 #[document_type_parameters("The lifetime of the elements.", "The element type.")]
819 #[document_parameters("The vector of options.")]
821 #[document_returns("A new vector containing the unwrapped `Some` values.")]
823 #[document_examples]
825 pub fn par_compact<'a, A: 'a + Send>(fa: Vec<Option<A>>) -> Vec<A> {
833 #[cfg(feature = "rayon")]
834 {
835 use rayon::prelude::*;
836 fa.into_par_iter().flatten().collect()
837 }
838 #[cfg(not(feature = "rayon"))]
839 fa.into_iter().flatten().collect()
840 }
841
842 #[document_signature]
847 #[document_type_parameters(
849 "The lifetime of the elements.",
850 "The error type.",
851 "The success type."
852 )]
853 #[document_parameters("The vector of results.")]
855 #[document_returns(
857 "A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
858 )]
859 #[document_examples]
861 pub fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
871 fa: Vec<Result<O, E>>
872 ) -> (Vec<E>, Vec<O>) {
873 #[cfg(feature = "rayon")]
874 {
875 use rayon::{
876 iter::Either,
877 prelude::*,
878 };
879 fa.into_par_iter().partition_map(|r| match r {
880 Ok(o) => Either::Right(o),
881 Err(e) => Either::Left(e),
882 })
883 }
884 #[cfg(not(feature = "rayon"))]
885 {
886 let mut errs = Vec::new();
887 let mut oks = Vec::new();
888 for result in fa {
889 match result {
890 Ok(o) => oks.push(o),
891 Err(e) => errs.push(e),
892 }
893 }
894 (errs, oks)
895 }
896 }
897
898 #[document_signature]
903 #[document_type_parameters(
905 "The lifetime of the elements.",
906 "The input element type.",
907 "The output element type."
908 )]
909 #[document_parameters(
911 "The function to apply. Must be `Send + Sync`.",
912 "The vector to filter and map."
913 )]
914 #[document_returns("A new vector containing the `Some` results of applying `f`.")]
916 #[document_examples]
918 pub fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
929 f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
930 fa: Vec<A>,
931 ) -> Vec<B> {
932 #[cfg(feature = "rayon")]
933 {
934 use rayon::prelude::*;
935 fa.into_par_iter().filter_map(f).collect()
936 }
937 #[cfg(not(feature = "rayon"))]
938 fa.into_iter().filter_map(f).collect()
939 }
940
941 #[document_signature]
946 #[document_type_parameters("The lifetime of the elements.", "The element type.")]
948 #[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
950 #[document_returns("A new vector containing only the elements satisfying `f`.")]
952 #[document_examples]
954 pub fn par_filter<'a, A: 'a + Send>(
962 f: impl Fn(&A) -> bool + Send + Sync + 'a,
963 fa: Vec<A>,
964 ) -> Vec<A> {
965 #[cfg(feature = "rayon")]
966 {
967 use rayon::prelude::*;
968 fa.into_par_iter().filter(|a| f(a)).collect()
969 }
970 #[cfg(not(feature = "rayon"))]
971 fa.into_iter().filter(|a| f(a)).collect()
972 }
973
974 #[document_signature]
979 #[document_type_parameters(
981 "The lifetime of the elements.",
982 "The element type.",
983 "The monoid type."
984 )]
985 #[document_parameters(
987 "The function mapping each element to a monoid value. Must be `Send + Sync`.",
988 "The vector to fold."
989 )]
990 #[document_returns("The combined monoid value.")]
992 #[document_examples]
994 pub fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1002 f: impl Fn(A) -> M + Send + Sync + 'a,
1003 fa: Vec<A>,
1004 ) -> M {
1005 #[cfg(feature = "rayon")]
1006 {
1007 use rayon::prelude::*;
1008 fa.into_par_iter().map(f).reduce(M::empty, |acc, m| M::append(acc, m))
1009 }
1010 #[cfg(not(feature = "rayon"))]
1011 fa.into_iter().map(f).fold(M::empty(), |acc, m| M::append(acc, m))
1012 }
1013
1014 #[document_signature]
1019 #[document_type_parameters(
1021 "The lifetime of the elements.",
1022 "The input element type.",
1023 "The output element type."
1024 )]
1025 #[document_parameters(
1027 "The function to apply to each index and element. Must be `Send + Sync`.",
1028 "The vector to map over."
1029 )]
1030 #[document_returns("A new vector containing the mapped elements.")]
1032 #[document_examples]
1034 pub fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1042 f: impl Fn(usize, A) -> B + Send + Sync + 'a,
1043 fa: Vec<A>,
1044 ) -> Vec<B> {
1045 #[cfg(feature = "rayon")]
1046 {
1047 use rayon::prelude::*;
1048 fa.into_par_iter().enumerate().map(|(i, a)| f(i, a)).collect()
1049 }
1050 #[cfg(not(feature = "rayon"))]
1051 fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
1052 }
1053
1054 #[document_signature]
1059 #[document_type_parameters(
1061 "The lifetime of the elements.",
1062 "The element type.",
1063 "The monoid type."
1064 )]
1065 #[document_parameters(
1067 "The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
1068 "The vector to fold."
1069 )]
1070 #[document_returns("The combined monoid value.")]
1072 #[document_examples]
1074 pub fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1083 f: impl Fn(usize, A) -> M + Send + Sync + 'a,
1084 fa: Vec<A>,
1085 ) -> M {
1086 #[cfg(feature = "rayon")]
1087 {
1088 use rayon::prelude::*;
1089 fa.into_par_iter()
1090 .enumerate()
1091 .map(|(i, a)| f(i, a))
1092 .reduce(M::empty, |acc, m| M::append(acc, m))
1093 }
1094 #[cfg(not(feature = "rayon"))]
1095 fa.into_iter()
1096 .enumerate()
1097 .map(|(i, a)| f(i, a))
1098 .fold(M::empty(), |acc, m| M::append(acc, m))
1099 }
1100 }
1101
1102 impl ParFunctor for VecBrand {
1103 #[document_signature]
1107 #[document_type_parameters(
1109 "The lifetime of the elements.",
1110 "The input element type.",
1111 "The output element type."
1112 )]
1113 #[document_parameters(
1115 "The function to apply to each element. Must be `Send + Sync`.",
1116 "The vector to map over."
1117 )]
1118 #[document_returns("A new vector containing the mapped elements.")]
1120 #[document_examples]
1122 fn par_map<'a, A: 'a + Send, B: 'a + Send>(
1133 f: impl Fn(A) -> B + Send + Sync + 'a,
1134 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1135 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1136 VecBrand::par_map(f, fa)
1137 }
1138 }
1139
1140 impl ParCompactable for VecBrand {
1141 #[document_signature]
1145 #[document_type_parameters("The lifetime of the elements.", "The element type.")]
1147 #[document_parameters("The vector of options.")]
1149 #[document_returns("A new vector containing the unwrapped `Some` values.")]
1151 #[document_examples]
1153 fn par_compact<'a, A: 'a + Send>(
1164 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1165 'a,
1166 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1167 >)
1168 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1169 VecBrand::par_compact(fa)
1170 }
1171
1172 #[document_signature]
1176 #[document_type_parameters(
1178 "The lifetime of the elements.",
1179 "The error type.",
1180 "The success type."
1181 )]
1182 #[document_parameters("The vector of results.")]
1184 #[document_returns(
1186 "A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
1187 )]
1188 #[document_examples]
1190 fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
1203 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1204 ) -> (
1205 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1206 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1207 ) {
1208 VecBrand::par_separate(fa)
1209 }
1210 }
1211
1212 impl ParFilterable for VecBrand {
1213 #[document_signature]
1218 #[document_type_parameters(
1220 "The lifetime of the elements.",
1221 "The input element type.",
1222 "The output element type."
1223 )]
1224 #[document_parameters(
1226 "The function to apply. Must be `Send + Sync`.",
1227 "The vector to filter and map."
1228 )]
1229 #[document_returns("A new vector containing the `Some` results of applying `f`.")]
1231 #[document_examples]
1233 fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
1247 f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
1248 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1249 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1250 VecBrand::par_filter_map(f, fa)
1251 }
1252
1253 #[document_signature]
1258 #[document_type_parameters("The lifetime of the elements.", "The element type.")]
1260 #[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
1262 #[document_returns("A new vector containing only the elements satisfying `f`.")]
1264 #[document_examples]
1266 fn par_filter<'a, A: 'a + Send>(
1277 f: impl Fn(&A) -> bool + Send + Sync + 'a,
1278 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1279 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1280 VecBrand::par_filter(f, fa)
1281 }
1282 }
1283
1284 impl ParFoldable for VecBrand {
1285 #[document_signature]
1289 #[document_type_parameters(
1291 "The lifetime of the elements.",
1292 "The element type.",
1293 "The monoid type."
1294 )]
1295 #[document_parameters(
1297 "The function mapping each element to a monoid value. Must be `Send + Sync`.",
1298 "The vector to fold."
1299 )]
1300 #[document_returns("The combined monoid value.")]
1302 #[document_examples]
1304 fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1315 f: impl Fn(A) -> M + Send + Sync + 'a,
1316 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1317 ) -> M {
1318 VecBrand::par_fold_map(f, fa)
1319 }
1320 }
1321
1322 impl ParFunctorWithIndex for VecBrand {
1323 #[document_signature]
1327 #[document_type_parameters(
1329 "The lifetime of the elements.",
1330 "The input element type.",
1331 "The output element type."
1332 )]
1333 #[document_parameters(
1335 "The function to apply to each index and element. Must be `Send + Sync`.",
1336 "The vector to map over."
1337 )]
1338 #[document_returns("A new vector containing the mapped elements.")]
1340 #[document_examples]
1342 fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1353 f: impl Fn(usize, A) -> B + Send + Sync + 'a,
1354 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1355 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
1356 where
1357 usize: Send + Sync + Copy + 'a, {
1358 VecBrand::par_map_with_index(f, fa)
1359 }
1360 }
1361
1362 impl ParFoldableWithIndex for VecBrand {
1363 #[document_signature]
1367 #[document_type_parameters(
1369 "The lifetime of the elements.",
1370 "The element type.",
1371 "The monoid type."
1372 )]
1373 #[document_parameters(
1375 "The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
1376 "The vector to fold."
1377 )]
1378 #[document_returns("The combined monoid value.")]
1380 #[document_examples]
1382 fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1394 f: impl Fn(usize, A) -> M + Send + Sync + 'a,
1395 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1396 ) -> M
1397 where
1398 usize: Send + Sync + Copy + 'a, {
1399 VecBrand::par_fold_map_with_index(f, fa)
1400 }
1401 }
1402
1403 impl Compactable for VecBrand {
1404 #[document_signature]
1408 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1410 #[document_parameters("The vector of options.")]
1412 #[document_returns("The flattened vector.")]
1414 #[document_examples]
1416 fn compact<'a, A: 'a>(
1428 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1429 'a,
1430 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1431 >)
1432 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1433 fa.into_iter().flatten().collect()
1434 }
1435
1436 #[document_signature]
1440 #[document_type_parameters(
1442 "The lifetime of the elements.",
1443 "The type of the error value.",
1444 "The type of the success value."
1445 )]
1446 #[document_parameters("The vector of results.")]
1448 #[document_returns("A pair of vectors.")]
1450 #[document_examples]
1452 fn separate<'a, E: 'a, O: 'a>(
1465 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1466 ) -> (
1467 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1468 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1469 ) {
1470 let mut oks = Vec::new();
1471 let mut errs = Vec::new();
1472 for result in fa {
1473 match result {
1474 Ok(o) => oks.push(o),
1475 Err(e) => errs.push(e),
1476 }
1477 }
1478 (errs, oks)
1479 }
1480 }
1481
1482 impl Filterable for VecBrand {
1483 #[document_signature]
1487 #[document_type_parameters(
1489 "The lifetime of the elements.",
1490 "The type of the input value.",
1491 "The type of the error value.",
1492 "The type of the success value."
1493 )]
1494 #[document_parameters("The function to apply.", "The vector to partition.")]
1496 #[document_returns("A pair of vectors.")]
1498 #[document_examples]
1500 fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
1514 func: impl Fn(A) -> Result<O, E> + 'a,
1515 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1516 ) -> (
1517 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1518 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1519 ) {
1520 let mut oks = Vec::new();
1521 let mut errs = Vec::new();
1522 for a in fa {
1523 match func(a) {
1524 Ok(o) => oks.push(o),
1525 Err(e) => errs.push(e),
1526 }
1527 }
1528 (errs, oks)
1529 }
1530
1531 #[document_signature]
1535 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1537 #[document_parameters("The predicate.", "The vector to partition.")]
1539 #[document_returns("A pair of vectors.")]
1541 #[document_examples]
1543 fn partition<'a, A: 'a + Clone>(
1556 func: impl Fn(A) -> bool + 'a,
1557 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1558 ) -> (
1559 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1560 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1561 ) {
1562 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
1563 fa.into_iter().partition(|a| func(a.clone()));
1564 (not_satisfied, satisfied)
1565 }
1566
1567 #[document_signature]
1571 #[document_type_parameters(
1573 "The lifetime of the elements.",
1574 "The type of the input value.",
1575 "The type of the result of applying the function."
1576 )]
1577 #[document_parameters("The function to apply.", "The vector to filter and map.")]
1579 #[document_returns("The filtered and mapped vector.")]
1581 #[document_examples]
1583 fn filter_map<'a, A: 'a, B: 'a>(
1595 func: impl Fn(A) -> Option<B> + 'a,
1596 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1597 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1598 fa.into_iter().filter_map(func).collect()
1599 }
1600
1601 #[document_signature]
1605 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1607 #[document_parameters("The predicate.", "The vector to filter.")]
1609 #[document_returns("The filtered vector.")]
1611 #[document_examples]
1613 fn filter<'a, A: 'a + Clone>(
1625 func: impl Fn(A) -> bool + 'a,
1626 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1627 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1628 fa.into_iter().filter(|a| func(a.clone())).collect()
1629 }
1630 }
1631
1632 impl Witherable for VecBrand {
1633 #[document_signature]
1637 #[document_type_parameters(
1639 "The lifetime of the elements.",
1640 "The applicative context.",
1641 "The type of the input value.",
1642 "The type of the error value.",
1643 "The type of the success value."
1644 )]
1645 #[document_parameters("The function to apply.", "The vector to partition.")]
1647 #[document_returns("The partitioned vector wrapped in the applicative context.")]
1649 #[document_examples]
1651 fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1666 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1667 + 'a,
1668 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1669 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1670 'a,
1671 (
1672 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1673 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1674 ),
1675 >)
1676 where
1677 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1678 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1679 ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
1680 M::lift2(
1681 |mut pair, res| {
1682 match res {
1683 Ok(o) => pair.1.push(o),
1684 Err(e) => pair.0.push(e),
1685 }
1686 pair
1687 },
1688 acc,
1689 func(x),
1690 )
1691 })
1692 }
1693
1694 #[document_signature]
1698 #[document_type_parameters(
1700 "The lifetime of the values.",
1701 "The applicative context.",
1702 "The type of the elements in the input structure.",
1703 "The type of the result of applying the function."
1704 )]
1705 #[document_parameters(
1707 "The function to apply to each element, returning an `Option` in an applicative context.",
1708 "The vector to filter and map."
1709 )]
1710 #[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
1712 #[document_examples]
1713 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1731 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1732 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1733 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1734 'a,
1735 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1736 >)
1737 where
1738 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1739 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1740 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1741 M::lift2(
1742 |mut v, opt_b| {
1743 if let Some(b) = opt_b {
1744 v.push(b);
1745 }
1746 v
1747 },
1748 acc,
1749 func(x),
1750 )
1751 })
1752 }
1753 }
1754}
1755
1756#[cfg(test)]
1757mod tests {
1758
1759 use {
1760 crate::{
1761 brands::*,
1762 classes::CloneableFn,
1763 functions::*,
1764 },
1765 quickcheck_macros::quickcheck,
1766 };
1767
1768 #[quickcheck]
1772 fn functor_identity(x: Vec<i32>) -> bool {
1773 map::<VecBrand, _, _>(identity, x.clone()) == x
1774 }
1775
1776 #[quickcheck]
1778 fn functor_composition(x: Vec<i32>) -> bool {
1779 let f = |x: i32| x.wrapping_add(1);
1780 let g = |x: i32| x.wrapping_mul(2);
1781 map::<VecBrand, _, _>(compose(f, g), x.clone())
1782 == map::<VecBrand, _, _>(f, map::<VecBrand, _, _>(g, x))
1783 }
1784
1785 #[quickcheck]
1789 fn applicative_identity(v: Vec<i32>) -> bool {
1790 apply::<RcFnBrand, VecBrand, _, _>(
1791 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1792 v.clone(),
1793 ) == v
1794 }
1795
1796 #[quickcheck]
1798 fn applicative_homomorphism(x: i32) -> bool {
1799 let f = |x: i32| x.wrapping_mul(2);
1800 apply::<RcFnBrand, VecBrand, _, _>(
1801 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1802 pure::<VecBrand, _>(x),
1803 ) == pure::<VecBrand, _>(f(x))
1804 }
1805
1806 #[quickcheck]
1808 fn applicative_composition(
1809 w: Vec<i32>,
1810 u_seeds: Vec<i32>,
1811 v_seeds: Vec<i32>,
1812 ) -> bool {
1813 let u_fns: Vec<_> = u_seeds
1814 .iter()
1815 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1816 .collect();
1817 let v_fns: Vec<_> = v_seeds
1818 .iter()
1819 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1820 .collect();
1821
1822 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1824 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1825
1826 let uv_fns: Vec<_> = u_fns
1830 .iter()
1831 .flat_map(|uf| {
1832 v_fns.iter().map(move |vf| {
1833 let uf = uf.clone();
1834 let vf = vf.clone();
1835 <RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1836 })
1837 })
1838 .collect();
1839
1840 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1841
1842 lhs == rhs
1843 }
1844
1845 #[quickcheck]
1847 fn applicative_interchange(y: i32) -> bool {
1848 let f = |x: i32| x.wrapping_mul(2);
1850 let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1851
1852 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1853
1854 let rhs_fn =
1855 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1856 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1857
1858 lhs == rhs
1859 }
1860
1861 #[quickcheck]
1865 fn semigroup_associativity(
1866 a: Vec<i32>,
1867 b: Vec<i32>,
1868 c: Vec<i32>,
1869 ) -> bool {
1870 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1871 }
1872
1873 #[quickcheck]
1877 fn monoid_left_identity(a: Vec<i32>) -> bool {
1878 append(empty::<Vec<i32>>(), a.clone()) == a
1879 }
1880
1881 #[quickcheck]
1883 fn monoid_right_identity(a: Vec<i32>) -> bool {
1884 append(a.clone(), empty::<Vec<i32>>()) == a
1885 }
1886
1887 #[quickcheck]
1891 fn monad_left_identity(a: i32) -> bool {
1892 let f = |x: i32| vec![x.wrapping_mul(2)];
1893 bind::<VecBrand, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1894 }
1895
1896 #[quickcheck]
1898 fn monad_right_identity(m: Vec<i32>) -> bool {
1899 bind::<VecBrand, _, _>(m.clone(), pure::<VecBrand, _>) == m
1900 }
1901
1902 #[quickcheck]
1904 fn monad_associativity(m: Vec<i32>) -> bool {
1905 let f = |x: i32| vec![x.wrapping_mul(2)];
1906 let g = |x: i32| vec![x.wrapping_add(1)];
1907 bind::<VecBrand, _, _>(bind::<VecBrand, _, _>(m.clone(), f), g)
1908 == bind::<VecBrand, _, _>(m, |x| bind::<VecBrand, _, _>(f(x), g))
1909 }
1910
1911 #[test]
1915 fn map_empty() {
1916 assert_eq!(map::<VecBrand, _, _>(|x: i32| x + 1, vec![] as Vec<i32>), vec![] as Vec<i32>);
1917 }
1918
1919 #[test]
1921 fn bind_empty() {
1922 assert_eq!(
1923 bind::<VecBrand, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1924 vec![] as Vec<i32>
1925 );
1926 }
1927
1928 #[test]
1930 fn bind_returning_empty() {
1931 assert_eq!(
1932 bind::<VecBrand, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1933 vec![] as Vec<i32>
1934 );
1935 }
1936
1937 #[test]
1939 fn fold_right_empty() {
1940 assert_eq!(
1941 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _>(
1942 |x: i32, acc| x + acc,
1943 0,
1944 vec![]
1945 ),
1946 0
1947 );
1948 }
1949
1950 #[test]
1952 fn fold_left_empty() {
1953 assert_eq!(
1954 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _>(
1955 |acc, x: i32| acc + x,
1956 0,
1957 vec![]
1958 ),
1959 0
1960 );
1961 }
1962
1963 #[test]
1965 fn traverse_empty() {
1966 use crate::brands::OptionBrand;
1967 assert_eq!(
1968 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1969 |x: i32| Some(x + 1),
1970 vec![]
1971 ),
1972 Some(vec![])
1973 );
1974 }
1975
1976 #[test]
1978 fn traverse_returning_empty() {
1979 use crate::brands::OptionBrand;
1980 assert_eq!(
1981 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1982 |_: i32| None::<i32>,
1983 vec![1, 2, 3]
1984 ),
1985 None
1986 );
1987 }
1988
1989 #[test]
1991 fn construct_empty_tail() {
1992 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1993 }
1994
1995 #[test]
1997 fn deconstruct_empty() {
1998 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1999 }
2000
2001 #[test]
2005 fn par_map_basic() {
2006 let v = vec![1, 2, 3];
2007 let result: Vec<i32> = par_map::<VecBrand, _, _>(|x: i32| x * 2, v);
2008 assert_eq!(result, vec![2, 4, 6]);
2009 }
2010
2011 #[test]
2013 fn par_filter_basic() {
2014 let v = vec![1, 2, 3, 4, 5];
2015 let result: Vec<i32> = par_filter::<VecBrand, _>(|x: &i32| x % 2 == 0, v);
2016 assert_eq!(result, vec![2, 4]);
2017 }
2018
2019 #[test]
2021 fn par_filter_map_basic() {
2022 let v = vec![1, 2, 3, 4, 5];
2023 let result: Vec<i32> = par_filter_map::<VecBrand, _, _>(
2024 |x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
2025 v,
2026 );
2027 assert_eq!(result, vec![20, 40]);
2028 }
2029
2030 #[test]
2032 fn par_compact_basic() {
2033 let v = vec![Some(1), None, Some(3), None, Some(5)];
2034 let result: Vec<i32> = par_compact::<VecBrand, _>(v);
2035 assert_eq!(result, vec![1, 3, 5]);
2036 }
2037
2038 #[test]
2040 fn par_separate_basic() {
2041 let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3), Err("b")];
2042 let (errs, oks): (Vec<&str>, Vec<i32>) = par_separate::<VecBrand, _, _>(v);
2043 assert_eq!(errs, vec!["a", "b"]);
2044 assert_eq!(oks, vec![1, 3]);
2045 }
2046
2047 #[test]
2049 fn par_map_with_index_basic() {
2050 let v = vec![10, 20, 30];
2051 let result: Vec<i32> = par_map_with_index::<VecBrand, _, _>(|i, x: i32| x + i as i32, v);
2052 assert_eq!(result, vec![10, 21, 32]);
2053 }
2054
2055 #[test]
2057 fn par_fold_map_empty() {
2058 let v: Vec<i32> = vec![];
2059 assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "".to_string());
2060 }
2061
2062 #[test]
2064 fn par_fold_map_multiple() {
2065 let v = vec![1, 2, 3];
2066 assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "123".to_string());
2067 }
2068
2069 #[test]
2071 fn par_fold_map_with_index_basic() {
2072 let v = vec![10, 20, 30];
2073 let result: String =
2074 par_fold_map_with_index::<VecBrand, _, _>(|i, x: i32| format!("{i}:{x}"), v);
2075 assert_eq!(result, "0:101:202:30");
2076 }
2077
2078 #[quickcheck]
2082 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
2083 filter_map::<VecBrand, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
2084 }
2085
2086 #[quickcheck]
2088 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
2089 filter_map::<VecBrand, _, _>(Some, x.clone()) == x
2090 }
2091
2092 #[quickcheck]
2094 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
2095 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
2096 let l = |i: i32| if i > 5 { Some(i) } else { None };
2097 let composed = |i| bind::<OptionBrand, _, _>(r(i), l);
2098
2099 filter_map::<VecBrand, _, _>(composed, x.clone())
2100 == filter_map::<VecBrand, _, _>(l, filter_map::<VecBrand, _, _>(r, x))
2101 }
2102
2103 #[quickcheck]
2105 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
2106 let p = |i: i32| i % 2 == 0;
2107 let maybe_bool = |i| if p(i) { Some(i) } else { None };
2108
2109 filter::<VecBrand, _>(p, x.clone()) == filter_map::<VecBrand, _, _>(maybe_bool, x)
2110 }
2111
2112 #[quickcheck]
2114 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
2115 partition_map::<VecBrand, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
2116 }
2117
2118 #[quickcheck]
2120 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
2121 let (_, oks) = partition_map::<VecBrand, _, _, _>(Ok::<_, i32>, x.clone());
2122 oks == x
2123 }
2124
2125 #[quickcheck]
2127 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
2128 let (errs, _) = partition_map::<VecBrand, _, _, _>(Err::<i32, _>, x.clone());
2129 errs == x
2130 }
2131
2132 #[quickcheck]
2134 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
2135 let p = |i: i32| i % 2 == 0;
2136 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
2137
2138 let (not_satisfied, satisfied) = partition::<VecBrand, _>(p, x.clone());
2139 let (errs, oks) = partition_map::<VecBrand, _, _, _>(either_bool, x);
2140
2141 satisfied == oks && not_satisfied == errs
2142 }
2143
2144 #[quickcheck]
2148 fn witherable_identity(x: Vec<i32>) -> bool {
2149 wither::<VecBrand, OptionBrand, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
2150 }
2151
2152 #[quickcheck]
2154 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
2155 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
2156
2157 let lhs = wilt::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
2158 let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
2159 separate::<VecBrand, _, _>,
2160 traverse::<VecBrand, _, _, OptionBrand>(p, x),
2161 );
2162
2163 lhs == rhs
2164 }
2165
2166 #[quickcheck]
2168 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
2169 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
2170
2171 let lhs = wither::<VecBrand, OptionBrand, _, _>(p, x.clone());
2172 let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
2173 compact::<VecBrand, _>,
2174 traverse::<VecBrand, _, _, OptionBrand>(p, x),
2175 );
2176
2177 lhs == rhs
2178 }
2179
2180 #[quickcheck]
2184 fn alt_associativity(
2185 x: Vec<i32>,
2186 y: Vec<i32>,
2187 z: Vec<i32>,
2188 ) -> bool {
2189 alt::<VecBrand, _>(alt::<VecBrand, _>(x.clone(), y.clone()), z.clone())
2190 == alt::<VecBrand, _>(x, alt::<VecBrand, _>(y, z))
2191 }
2192
2193 #[quickcheck]
2195 fn alt_distributivity(
2196 x: Vec<i32>,
2197 y: Vec<i32>,
2198 ) -> bool {
2199 let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
2200 map::<VecBrand, _, _>(f, alt::<VecBrand, _>(x.clone(), y.clone()))
2201 == alt::<VecBrand, _>(map::<VecBrand, _, _>(f, x), map::<VecBrand, _, _>(f, y))
2202 }
2203
2204 #[quickcheck]
2208 fn plus_left_identity(x: Vec<i32>) -> bool {
2209 alt::<VecBrand, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
2210 }
2211
2212 #[quickcheck]
2214 fn plus_right_identity(x: Vec<i32>) -> bool {
2215 alt::<VecBrand, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
2216 }
2217
2218 #[test]
2220 fn plus_annihilation() {
2221 let f = |i: i32| i.wrapping_mul(2);
2222 assert_eq!(
2223 map::<VecBrand, _, _>(f, plus_empty::<VecBrand, i32>()),
2224 plus_empty::<VecBrand, i32>(),
2225 );
2226 }
2227
2228 #[quickcheck]
2232 fn compactable_functor_identity(fa: Vec<i32>) -> bool {
2233 compact::<VecBrand, _>(map::<VecBrand, _, _>(Some, fa.clone())) == fa
2234 }
2235
2236 #[test]
2238 fn compactable_plus_annihilation_empty() {
2239 assert_eq!(
2240 compact::<VecBrand, _>(plus_empty::<VecBrand, Option<i32>>()),
2241 plus_empty::<VecBrand, i32>(),
2242 );
2243 }
2244
2245 #[quickcheck]
2247 fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
2248 compact::<VecBrand, _>(map::<VecBrand, _, _>(|_: i32| None::<i32>, xs))
2249 == plus_empty::<VecBrand, i32>()
2250 }
2251
2252 #[test]
2256 fn compact_empty() {
2257 assert_eq!(compact::<VecBrand, i32>(vec![] as Vec<Option<i32>>), vec![] as Vec<i32>);
2258 }
2259
2260 #[test]
2262 fn compact_with_none() {
2263 assert_eq!(compact::<VecBrand, i32>(vec![Some(1), None, Some(2)]), vec![1, 2]);
2264 }
2265
2266 #[test]
2268 fn separate_empty() {
2269 let (errs, oks) = separate::<VecBrand, i32, i32>(vec![] as Vec<Result<i32, i32>>);
2270 assert_eq!(oks, vec![] as Vec<i32>);
2271 assert_eq!(errs, vec![] as Vec<i32>);
2272 }
2273
2274 #[test]
2276 fn separate_mixed() {
2277 let (errs, oks) = separate::<VecBrand, i32, i32>(vec![Ok(1), Err(2), Ok(3)]);
2278 assert_eq!(oks, vec![1, 3]);
2279 assert_eq!(errs, vec![2]);
2280 }
2281
2282 #[test]
2284 fn partition_map_empty() {
2285 let (errs, oks) =
2286 partition_map::<VecBrand, i32, i32, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
2287 assert_eq!(oks, vec![] as Vec<i32>);
2288 assert_eq!(errs, vec![] as Vec<i32>);
2289 }
2290
2291 #[test]
2293 fn partition_empty() {
2294 let (not_satisfied, satisfied) = partition::<VecBrand, i32>(|x: i32| x > 0, vec![]);
2295 assert_eq!(satisfied, vec![] as Vec<i32>);
2296 assert_eq!(not_satisfied, vec![] as Vec<i32>);
2297 }
2298
2299 #[test]
2301 fn filter_map_empty() {
2302 assert_eq!(filter_map::<VecBrand, i32, _>(|x: i32| Some(x), vec![]), vec![] as Vec<i32>);
2303 }
2304
2305 #[test]
2307 fn filter_empty() {
2308 assert_eq!(filter::<VecBrand, i32>(|x: i32| x > 0, vec![]), vec![] as Vec<i32>);
2309 }
2310
2311 #[test]
2313 fn wilt_empty() {
2314 let res = wilt::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
2315 assert_eq!(res, Some((vec![], vec![])));
2316 }
2317
2318 #[test]
2320 fn wither_empty() {
2321 let res = wither::<VecBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), vec![]);
2322 assert_eq!(res, Some(vec![]));
2323 }
2324
2325 #[test]
2329 fn test_large_vector_par_fold_map() {
2330 use crate::types::Additive;
2331
2332 let xs: Vec<i32> = (0 .. 100000).collect();
2333 let res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
2334 assert_eq!(res, Additive(4999950000));
2335 }
2336
2337 #[quickcheck]
2339 fn prop_par_map_equals_map(xs: Vec<i32>) -> bool {
2340 let f = |x: i32| x.wrapping_add(1);
2341 let seq_res = map::<VecBrand, _, _>(f, xs.clone());
2342 let par_res = par_map::<VecBrand, _, _>(f, xs);
2343 seq_res == par_res
2344 }
2345
2346 #[quickcheck]
2348 fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
2349 use crate::types::Additive;
2350
2351 let f = |x: i32| Additive(x as i64);
2352 let seq_res = crate::classes::foldable::fold_map::<crate::brands::RcFnBrand, VecBrand, _, _>(
2353 f,
2354 xs.clone(),
2355 );
2356 let par_res = par_fold_map::<VecBrand, _, _>(f, xs);
2357 seq_res == par_res
2358 }
2359
2360 #[quickcheck]
2362 fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
2363 use crate::types::Additive;
2364
2365 if !xs.is_empty() {
2366 return true;
2367 }
2368 let par_res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
2369 par_res == empty::<Additive<i64>>()
2370 }
2371}