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 Applicative,
18 ApplyFirst,
19 ApplySecond,
20 CloneableFn,
21 Compactable,
22 Filterable,
23 Foldable,
24 Functor,
25 Lift,
26 Monoid,
27 ParFoldable,
28 Pointed,
29 Semiapplicative,
30 Semigroup,
31 Semimonad,
32 SendCloneableFn,
33 Traversable,
34 Witherable,
35 foldable_with_index::FoldableWithIndex,
36 functor_with_index::FunctorWithIndex,
37 traversable_with_index::TraversableWithIndex,
38 },
39 impl_kind,
40 kinds::*,
41 },
42 fp_macros::*,
43 };
44
45 impl_kind! {
46 for VecBrand {
47 type Of<'a, A: 'a>: 'a = Vec<A>;
48 }
49 }
50
51 impl VecBrand {
52 #[document_signature]
56 #[document_type_parameters("The type of the elements in the vector.")]
58 #[document_parameters(
60 "A value to prepend to the vector.",
61 "A vector to prepend the value to."
62 )]
63 #[document_returns(
65 "A new vector consisting of the `head` element prepended to the `tail` vector."
66 )]
67 #[document_examples]
68 pub fn construct<A>(
82 head: A,
83 tail: Vec<A>,
84 ) -> Vec<A>
85 where
86 A: Clone, {
87 [vec![head], tail].concat()
88 }
89
90 #[document_signature]
94 #[document_type_parameters("The type of the elements in the vector.")]
96 #[document_parameters("The vector slice to deconstruct.")]
98 #[document_returns(
100 "An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
101 )]
102 #[document_examples]
104 pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
116 where
117 A: Clone, {
118 match slice {
119 [] => None,
120 [head, tail @ ..] => Some((head.clone(), tail.to_vec())),
121 }
122 }
123 }
124
125 impl Functor for VecBrand {
126 #[document_signature]
130 #[document_type_parameters(
132 "The lifetime of the elements.",
133 "The type of the elements in the vector.",
134 "The type of the elements in the resulting vector."
135 )]
136 #[document_parameters("The function to apply to each element.", "The vector to map over.")]
138 #[document_returns("A new vector containing the results of applying the function.")]
140 #[document_examples]
142 fn map<'a, A: 'a, B: 'a>(
152 func: impl Fn(A) -> B + 'a,
153 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
154 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
155 fa.into_iter().map(func).collect()
156 }
157 }
158
159 impl Lift for VecBrand {
160 #[document_signature]
164 #[document_type_parameters(
166 "The lifetime of the elements.",
167 "The type of the elements in the first vector.",
168 "The type of the elements in the second vector.",
169 "The type of the elements in the resulting vector."
170 )]
171 #[document_parameters(
173 "The binary function to apply.",
174 "The first vector.",
175 "The second vector."
176 )]
177 #[document_returns(
179 "A new vector containing the results of applying the function to all pairs of elements."
180 )]
181 #[document_examples]
182 fn lift2<'a, A, B, C>(
195 func: impl Fn(A, B) -> C + 'a,
196 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
197 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
198 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
199 where
200 A: Clone + 'a,
201 B: Clone + 'a,
202 C: 'a, {
203 fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
204 }
205 }
206
207 impl Pointed for VecBrand {
208 #[document_signature]
212 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
214 #[document_parameters("The value to wrap.")]
216 #[document_returns("A vector containing the single value.")]
218 #[document_examples]
220 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
230 vec![a]
231 }
232 }
233
234 impl ApplyFirst for VecBrand {}
235 impl ApplySecond for VecBrand {}
236
237 impl Semiapplicative for VecBrand {
238 #[document_signature]
242 #[document_type_parameters(
244 "The lifetime of the values.",
245 "The brand of the cloneable function wrapper.",
246 "The type of the input values.",
247 "The type of the output values."
248 )]
249 #[document_parameters(
251 "The vector containing the functions.",
252 "The vector containing the values."
253 )]
254 #[document_returns(
256 "A new vector containing the results of applying each function to each value."
257 )]
258 #[document_examples]
259 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
274 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
275 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
276 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
277 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
278 }
279 }
280
281 impl Semimonad for VecBrand {
282 #[document_signature]
286 #[document_type_parameters(
288 "The lifetime of the elements.",
289 "The type of the elements in the input vector.",
290 "The type of the elements in the output vector."
291 )]
292 #[document_parameters(
294 "The first vector.",
295 "The function to apply to each element, returning a vector."
296 )]
297 #[document_returns("A new vector containing the flattened results.")]
299 #[document_examples]
300 fn bind<'a, A: 'a, B: 'a>(
310 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
311 func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
312 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
313 ma.into_iter().flat_map(func).collect()
314 }
315 }
316
317 impl Foldable for VecBrand {
318 #[document_signature]
322 #[document_type_parameters(
324 "The lifetime of the elements.",
325 "The brand of the cloneable function to use.",
326 "The type of the elements in the vector.",
327 "The type of the accumulator."
328 )]
329 #[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
331 #[document_returns("The final accumulator value.")]
333 #[document_examples]
335 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
345 func: impl Fn(A, B) -> B + 'a,
346 initial: B,
347 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
348 ) -> B
349 where
350 FnBrand: CloneableFn + 'a, {
351 fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
352 }
353
354 #[document_signature]
358 #[document_type_parameters(
360 "The lifetime of the elements.",
361 "The brand of the cloneable function to use.",
362 "The type of the elements in the vector.",
363 "The type of the accumulator."
364 )]
365 #[document_parameters(
367 "The function to apply to the accumulator and each element.",
368 "The initial value of the accumulator.",
369 "The vector to fold."
370 )]
371 #[document_returns("The final accumulator value.")]
373 #[document_examples]
374 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
384 func: impl Fn(B, A) -> B + 'a,
385 initial: B,
386 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
387 ) -> B
388 where
389 FnBrand: CloneableFn + 'a, {
390 fa.into_iter().fold(initial, func)
391 }
392
393 #[document_signature]
397 #[document_type_parameters(
399 "The lifetime of the elements.",
400 "The brand of the cloneable function to use.",
401 "The type of the elements in the vector.",
402 "The type of the monoid."
403 )]
404 #[document_parameters("The mapping function.", "The vector to fold.")]
406 #[document_returns("The combined monoid value.")]
408 #[document_examples]
410 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
423 func: impl Fn(A) -> M + 'a,
424 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
425 ) -> M
426 where
427 M: Monoid + 'a,
428 FnBrand: CloneableFn + 'a, {
429 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
430 }
431 }
432
433 impl Traversable for VecBrand {
434 #[document_signature]
438 #[document_type_parameters(
440 "The lifetime of the elements.",
441 "The type of the elements in the traversable structure.",
442 "The type of the elements in the resulting traversable structure.",
443 "The applicative context."
444 )]
445 #[document_parameters(
447 "The function to apply to each element, returning a value in an applicative context.",
448 "The vector to traverse."
449 )]
450 #[document_returns("The vector wrapped in the applicative context.")]
452 #[document_examples]
453 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
469 func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
470 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
471 ) -> 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>)>)
472 where
473 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
474 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
475 let len = ta.len();
476 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
477 F::lift2(
478 |mut v, b| {
479 v.push(b);
480 v
481 },
482 acc,
483 func(x),
484 )
485 })
486 }
487
488 #[document_signature]
492 #[document_type_parameters(
494 "The lifetime of the elements.",
495 "The type of the elements in the traversable structure.",
496 "The applicative context."
497 )]
498 #[document_parameters("The vector containing the applicative values.")]
500 #[document_returns("The vector wrapped in the applicative context.")]
502 #[document_examples]
504 fn sequence<'a, A: 'a + Clone, F: Applicative>(
517 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>)>)
518 ) -> 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>)>)
519 where
520 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
521 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
522 let len = ta.len();
523 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
524 F::lift2(
525 |mut v, a| {
526 v.push(a);
527 v
528 },
529 acc,
530 x,
531 )
532 })
533 }
534 }
535
536 impl FunctorWithIndex<usize> for VecBrand {
537 #[document_signature]
539 #[document_type_parameters(
540 "The lifetime of the elements.",
541 "The type of the elements in the vector.",
542 "The type of the elements in the resulting vector."
543 )]
544 #[document_parameters(
545 "The function to apply to each element and its index.",
546 "The vector to map over."
547 )]
548 #[document_returns("A new vector containing the results of applying the function.")]
549 #[document_examples]
550 fn map_with_index<'a, A: 'a, B: 'a>(
564 f: impl Fn(usize, A) -> B + 'a,
565 fa: Vec<A>,
566 ) -> Vec<B> {
567 fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
568 }
569 }
570
571 impl FoldableWithIndex<usize> for VecBrand {
572 #[document_signature]
574 #[document_type_parameters(
575 "The lifetime of the elements.",
576 "The type of the elements in the vector.",
577 "The monoid type."
578 )]
579 #[document_parameters(
580 "The function to apply to each element and its index.",
581 "The vector to fold."
582 )]
583 #[document_returns("The combined monoid value.")]
584 #[document_examples]
585 fn fold_map_with_index<'a, A: 'a, R: Monoid>(
600 f: impl Fn(usize, A) -> R + 'a,
601 fa: Vec<A>,
602 ) -> R {
603 fa.into_iter()
604 .enumerate()
605 .map(|(i, a)| f(i, a))
606 .fold(R::empty(), |acc, x| R::append(acc, x))
607 }
608 }
609
610 impl TraversableWithIndex<usize> for VecBrand {
611 #[document_signature]
613 #[document_type_parameters(
614 "The lifetime of the elements.",
615 "The type of the elements in the vector.",
616 "The type of the elements in the resulting vector.",
617 "The applicative context."
618 )]
619 #[document_parameters(
620 "The function to apply to each element and its index, returning a value in an applicative context.",
621 "The vector to traverse."
622 )]
623 #[document_returns("The vector wrapped in the applicative context.")]
624 #[document_examples]
625 fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
643 f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
644 ta: Vec<A>,
645 ) -> M::Of<'a, Vec<B>> {
646 let len = ta.len();
647 ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
648 M::lift2(
649 |mut v, b| {
650 v.push(b);
651 v
652 },
653 acc,
654 f(i, x),
655 )
656 })
657 }
658 }
659
660 #[document_type_parameters("The type of the elements in the vector.")]
661 impl<A: Clone> Semigroup for Vec<A> {
662 #[document_signature]
666 #[document_parameters("The first vector.", "The second vector.")]
668 #[document_returns("The concatenated vector.")]
670 #[document_examples]
672 fn append(
679 a: Self,
680 b: Self,
681 ) -> Self {
682 [a, b].concat()
683 }
684 }
685
686 #[document_type_parameters("The type of the elements in the vector.")]
687 impl<A: Clone> Monoid for Vec<A> {
688 #[document_signature]
692 #[document_returns("An empty vector.")]
694 #[document_examples]
696 fn empty() -> Self {
703 Vec::new()
704 }
705 }
706
707 impl ParFoldable for VecBrand {
708 #[document_signature]
714 #[document_type_parameters(
716 "The lifetime of the elements.",
717 "The brand of the cloneable function wrapper.",
718 "The element type.",
719 "The monoid type."
720 )]
721 #[document_parameters(
723 "The thread-safe function to map each element to a monoid.",
724 "The vector to fold."
725 )]
726 #[document_returns("The combined monoid value.")]
728 #[document_examples]
729 fn par_fold_map<'a, FnBrand, A, M>(
741 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
742 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
743 ) -> M
744 where
745 FnBrand: 'a + SendCloneableFn,
746 A: 'a + Clone + Send + Sync,
747 M: Monoid + Send + Sync + 'a, {
748 #[cfg(feature = "rayon")]
749 {
750 #[allow(clippy::redundant_closure)] fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
752 }
753 #[cfg(not(feature = "rayon"))]
754 {
755 #[allow(clippy::redundant_closure)] fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
757 }
758 }
759 }
760
761 impl Compactable for VecBrand {
762 #[document_signature]
766 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
768 #[document_parameters("The vector of options.")]
770 #[document_returns("The flattened vector.")]
772 #[document_examples]
774 fn compact<'a, A: 'a>(
786 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
787 'a,
788 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
789 >)
790 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
791 fa.into_iter().flatten().collect()
792 }
793
794 #[document_signature]
798 #[document_type_parameters(
800 "The lifetime of the elements.",
801 "The type of the error value.",
802 "The type of the success value."
803 )]
804 #[document_parameters("The vector of results.")]
806 #[document_returns("A pair of vectors.")]
808 #[document_examples]
810 fn separate<'a, E: 'a, O: 'a>(
823 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
824 ) -> (
825 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
826 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
827 ) {
828 let mut oks = Vec::new();
829 let mut errs = Vec::new();
830 for result in fa {
831 match result {
832 Ok(o) => oks.push(o),
833 Err(e) => errs.push(e),
834 }
835 }
836 (errs, oks)
837 }
838 }
839
840 impl Filterable for VecBrand {
841 #[document_signature]
845 #[document_type_parameters(
847 "The lifetime of the elements.",
848 "The type of the input value.",
849 "The type of the error value.",
850 "The type of the success value."
851 )]
852 #[document_parameters("The function to apply.", "The vector to partition.")]
854 #[document_returns("A pair of vectors.")]
856 #[document_examples]
858 fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
872 func: impl Fn(A) -> Result<O, E> + 'a,
873 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
874 ) -> (
875 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
876 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
877 ) {
878 let mut oks = Vec::new();
879 let mut errs = Vec::new();
880 for a in fa {
881 match func(a) {
882 Ok(o) => oks.push(o),
883 Err(e) => errs.push(e),
884 }
885 }
886 (errs, oks)
887 }
888
889 #[document_signature]
893 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
895 #[document_parameters("The predicate.", "The vector to partition.")]
897 #[document_returns("A pair of vectors.")]
899 #[document_examples]
901 fn partition<'a, A: 'a + Clone>(
914 func: impl Fn(A) -> bool + 'a,
915 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
916 ) -> (
917 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
918 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
919 ) {
920 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
921 fa.into_iter().partition(|a| func(a.clone()));
922 (not_satisfied, satisfied)
923 }
924
925 #[document_signature]
929 #[document_type_parameters(
931 "The lifetime of the elements.",
932 "The type of the input value.",
933 "The type of the result of applying the function."
934 )]
935 #[document_parameters("The function to apply.", "The vector to filter and map.")]
937 #[document_returns("The filtered and mapped vector.")]
939 #[document_examples]
941 fn filter_map<'a, A: 'a, B: 'a>(
953 func: impl Fn(A) -> Option<B> + 'a,
954 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
955 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
956 fa.into_iter().filter_map(func).collect()
957 }
958
959 #[document_signature]
963 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
965 #[document_parameters("The predicate.", "The vector to filter.")]
967 #[document_returns("The filtered vector.")]
969 #[document_examples]
971 fn filter<'a, A: 'a + Clone>(
983 func: impl Fn(A) -> bool + 'a,
984 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
985 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
986 fa.into_iter().filter(|a| func(a.clone())).collect()
987 }
988 }
989
990 impl Witherable for VecBrand {
991 #[document_signature]
995 #[document_type_parameters(
997 "The lifetime of the elements.",
998 "The applicative context.",
999 "The type of the input value.",
1000 "The type of the error value.",
1001 "The type of the success value."
1002 )]
1003 #[document_parameters("The function to apply.", "The vector to partition.")]
1005 #[document_returns("The partitioned vector wrapped in the applicative context.")]
1007 #[document_examples]
1009 fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1024 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1025 + 'a,
1026 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1027 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1028 'a,
1029 (
1030 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1031 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1032 ),
1033 >)
1034 where
1035 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1036 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1037 ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
1038 M::lift2(
1039 |mut pair, res| {
1040 match res {
1041 Ok(o) => pair.1.push(o),
1042 Err(e) => pair.0.push(e),
1043 }
1044 pair
1045 },
1046 acc,
1047 func(x),
1048 )
1049 })
1050 }
1051
1052 #[document_signature]
1056 #[document_type_parameters(
1058 "The lifetime of the values.",
1059 "The applicative context.",
1060 "The type of the elements in the input structure.",
1061 "The type of the result of applying the function."
1062 )]
1063 #[document_parameters(
1065 "The function to apply to each element, returning an `Option` in an applicative context.",
1066 "The vector to filter and map."
1067 )]
1068 #[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
1070 #[document_examples]
1071 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1089 func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1090 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1091 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1092 'a,
1093 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1094 >)
1095 where
1096 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1097 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1098 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1099 M::lift2(
1100 |mut v, opt_b| {
1101 if let Some(b) = opt_b {
1102 v.push(b);
1103 }
1104 v
1105 },
1106 acc,
1107 func(x),
1108 )
1109 })
1110 }
1111 }
1112}
1113
1114#[cfg(test)]
1115mod tests {
1116
1117 use {
1118 crate::{
1119 brands::*,
1120 classes::CloneableFn,
1121 functions::*,
1122 },
1123 quickcheck_macros::quickcheck,
1124 };
1125
1126 #[quickcheck]
1130 fn functor_identity(x: Vec<i32>) -> bool {
1131 map::<VecBrand, _, _>(identity, x.clone()) == x
1132 }
1133
1134 #[quickcheck]
1136 fn functor_composition(x: Vec<i32>) -> bool {
1137 let f = |x: i32| x.wrapping_add(1);
1138 let g = |x: i32| x.wrapping_mul(2);
1139 map::<VecBrand, _, _>(compose(f, g), x.clone())
1140 == map::<VecBrand, _, _>(f, map::<VecBrand, _, _>(g, x))
1141 }
1142
1143 #[quickcheck]
1147 fn applicative_identity(v: Vec<i32>) -> bool {
1148 apply::<RcFnBrand, VecBrand, _, _>(
1149 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1150 v.clone(),
1151 ) == v
1152 }
1153
1154 #[quickcheck]
1156 fn applicative_homomorphism(x: i32) -> bool {
1157 let f = |x: i32| x.wrapping_mul(2);
1158 apply::<RcFnBrand, VecBrand, _, _>(
1159 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1160 pure::<VecBrand, _>(x),
1161 ) == pure::<VecBrand, _>(f(x))
1162 }
1163
1164 #[quickcheck]
1166 fn applicative_composition(
1167 w: Vec<i32>,
1168 u_seeds: Vec<i32>,
1169 v_seeds: Vec<i32>,
1170 ) -> bool {
1171 let u_fns: Vec<_> = u_seeds
1172 .iter()
1173 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1174 .collect();
1175 let v_fns: Vec<_> = v_seeds
1176 .iter()
1177 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1178 .collect();
1179
1180 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1182 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1183
1184 let uv_fns: Vec<_> = u_fns
1188 .iter()
1189 .flat_map(|uf| {
1190 v_fns.iter().map(move |vf| {
1191 let uf = uf.clone();
1192 let vf = vf.clone();
1193 <RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1194 })
1195 })
1196 .collect();
1197
1198 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1199
1200 lhs == rhs
1201 }
1202
1203 #[quickcheck]
1205 fn applicative_interchange(y: i32) -> bool {
1206 let f = |x: i32| x.wrapping_mul(2);
1208 let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1209
1210 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1211
1212 let rhs_fn =
1213 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1214 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1215
1216 lhs == rhs
1217 }
1218
1219 #[quickcheck]
1223 fn semigroup_associativity(
1224 a: Vec<i32>,
1225 b: Vec<i32>,
1226 c: Vec<i32>,
1227 ) -> bool {
1228 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1229 }
1230
1231 #[quickcheck]
1235 fn monoid_left_identity(a: Vec<i32>) -> bool {
1236 append(empty::<Vec<i32>>(), a.clone()) == a
1237 }
1238
1239 #[quickcheck]
1241 fn monoid_right_identity(a: Vec<i32>) -> bool {
1242 append(a.clone(), empty::<Vec<i32>>()) == a
1243 }
1244
1245 #[quickcheck]
1249 fn monad_left_identity(a: i32) -> bool {
1250 let f = |x: i32| vec![x.wrapping_mul(2)];
1251 bind::<VecBrand, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1252 }
1253
1254 #[quickcheck]
1256 fn monad_right_identity(m: Vec<i32>) -> bool {
1257 bind::<VecBrand, _, _>(m.clone(), pure::<VecBrand, _>) == m
1258 }
1259
1260 #[quickcheck]
1262 fn monad_associativity(m: Vec<i32>) -> bool {
1263 let f = |x: i32| vec![x.wrapping_mul(2)];
1264 let g = |x: i32| vec![x.wrapping_add(1)];
1265 bind::<VecBrand, _, _>(bind::<VecBrand, _, _>(m.clone(), f), g)
1266 == bind::<VecBrand, _, _>(m, |x| bind::<VecBrand, _, _>(f(x), g))
1267 }
1268
1269 #[test]
1273 fn map_empty() {
1274 assert_eq!(map::<VecBrand, _, _>(|x: i32| x + 1, vec![] as Vec<i32>), vec![] as Vec<i32>);
1275 }
1276
1277 #[test]
1279 fn bind_empty() {
1280 assert_eq!(
1281 bind::<VecBrand, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1282 vec![] as Vec<i32>
1283 );
1284 }
1285
1286 #[test]
1288 fn bind_returning_empty() {
1289 assert_eq!(
1290 bind::<VecBrand, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1291 vec![] as Vec<i32>
1292 );
1293 }
1294
1295 #[test]
1297 fn fold_right_empty() {
1298 assert_eq!(
1299 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _>(
1300 |x: i32, acc| x + acc,
1301 0,
1302 vec![]
1303 ),
1304 0
1305 );
1306 }
1307
1308 #[test]
1310 fn fold_left_empty() {
1311 assert_eq!(
1312 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _>(
1313 |acc, x: i32| acc + x,
1314 0,
1315 vec![]
1316 ),
1317 0
1318 );
1319 }
1320
1321 #[test]
1323 fn traverse_empty() {
1324 use crate::brands::OptionBrand;
1325 assert_eq!(
1326 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1327 |x: i32| Some(x + 1),
1328 vec![]
1329 ),
1330 Some(vec![])
1331 );
1332 }
1333
1334 #[test]
1336 fn traverse_returning_empty() {
1337 use crate::brands::OptionBrand;
1338 assert_eq!(
1339 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1340 |_: i32| None::<i32>,
1341 vec![1, 2, 3]
1342 ),
1343 None
1344 );
1345 }
1346
1347 #[test]
1349 fn construct_empty_tail() {
1350 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1351 }
1352
1353 #[test]
1355 fn deconstruct_empty() {
1356 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1357 }
1358
1359 #[test]
1363 fn par_fold_map_empty() {
1364 let v: Vec<i32> = vec![];
1365 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1366 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1367 }
1368
1369 #[test]
1371 fn par_fold_map_single() {
1372 let v = vec![1];
1373 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1374 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1375 }
1376
1377 #[test]
1379 fn par_fold_map_multiple() {
1380 let v = vec![1, 2, 3];
1381 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1382 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1383 }
1384
1385 #[test]
1387 fn par_fold_right_multiple() {
1388 let v = vec![1, 2, 3];
1389 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1390 assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1391 }
1392
1393 #[quickcheck]
1397 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1398 filter_map::<VecBrand, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1399 }
1400
1401 #[quickcheck]
1403 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1404 filter_map::<VecBrand, _, _>(Some, x.clone()) == x
1405 }
1406
1407 #[quickcheck]
1409 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1410 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1411 let l = |i: i32| if i > 5 { Some(i) } else { None };
1412 let composed = |i| bind::<OptionBrand, _, _>(r(i), l);
1413
1414 filter_map::<VecBrand, _, _>(composed, x.clone())
1415 == filter_map::<VecBrand, _, _>(l, filter_map::<VecBrand, _, _>(r, x))
1416 }
1417
1418 #[quickcheck]
1420 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1421 let p = |i: i32| i % 2 == 0;
1422 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1423
1424 filter::<VecBrand, _>(p, x.clone()) == filter_map::<VecBrand, _, _>(maybe_bool, x)
1425 }
1426
1427 #[quickcheck]
1429 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1430 partition_map::<VecBrand, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1431 }
1432
1433 #[quickcheck]
1435 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1436 let (_, oks) = partition_map::<VecBrand, _, _, _>(Ok::<_, i32>, x.clone());
1437 oks == x
1438 }
1439
1440 #[quickcheck]
1442 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1443 let (errs, _) = partition_map::<VecBrand, _, _, _>(Err::<i32, _>, x.clone());
1444 errs == x
1445 }
1446
1447 #[quickcheck]
1449 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1450 let p = |i: i32| i % 2 == 0;
1451 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1452
1453 let (not_satisfied, satisfied) = partition::<VecBrand, _>(p, x.clone());
1454 let (errs, oks) = partition_map::<VecBrand, _, _, _>(either_bool, x);
1455
1456 satisfied == oks && not_satisfied == errs
1457 }
1458
1459 #[quickcheck]
1463 fn witherable_identity(x: Vec<i32>) -> bool {
1464 wither::<VecBrand, OptionBrand, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1465 }
1466
1467 #[quickcheck]
1469 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1470 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1471
1472 let lhs = wilt::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1473 let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
1474 separate::<VecBrand, _, _>,
1475 traverse::<VecBrand, _, _, OptionBrand>(p, x),
1476 );
1477
1478 lhs == rhs
1479 }
1480
1481 #[quickcheck]
1483 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1484 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1485
1486 let lhs = wither::<VecBrand, OptionBrand, _, _>(p, x.clone());
1487 let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
1488 compact::<VecBrand, _>,
1489 traverse::<VecBrand, _, _, OptionBrand>(p, x),
1490 );
1491
1492 lhs == rhs
1493 }
1494
1495 #[test]
1499 fn compact_empty() {
1500 assert_eq!(compact::<VecBrand, i32>(vec![] as Vec<Option<i32>>), vec![] as Vec<i32>);
1501 }
1502
1503 #[test]
1505 fn compact_with_none() {
1506 assert_eq!(compact::<VecBrand, i32>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1507 }
1508
1509 #[test]
1511 fn separate_empty() {
1512 let (errs, oks) = separate::<VecBrand, i32, i32>(vec![] as Vec<Result<i32, i32>>);
1513 assert_eq!(oks, vec![] as Vec<i32>);
1514 assert_eq!(errs, vec![] as Vec<i32>);
1515 }
1516
1517 #[test]
1519 fn separate_mixed() {
1520 let (errs, oks) = separate::<VecBrand, i32, i32>(vec![Ok(1), Err(2), Ok(3)]);
1521 assert_eq!(oks, vec![1, 3]);
1522 assert_eq!(errs, vec![2]);
1523 }
1524
1525 #[test]
1527 fn partition_map_empty() {
1528 let (errs, oks) =
1529 partition_map::<VecBrand, i32, i32, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1530 assert_eq!(oks, vec![] as Vec<i32>);
1531 assert_eq!(errs, vec![] as Vec<i32>);
1532 }
1533
1534 #[test]
1536 fn partition_empty() {
1537 let (not_satisfied, satisfied) = partition::<VecBrand, i32>(|x: i32| x > 0, vec![]);
1538 assert_eq!(satisfied, vec![] as Vec<i32>);
1539 assert_eq!(not_satisfied, vec![] as Vec<i32>);
1540 }
1541
1542 #[test]
1544 fn filter_map_empty() {
1545 assert_eq!(filter_map::<VecBrand, i32, _>(|x: i32| Some(x), vec![]), vec![] as Vec<i32>);
1546 }
1547
1548 #[test]
1550 fn filter_empty() {
1551 assert_eq!(filter::<VecBrand, i32>(|x: i32| x > 0, vec![]), vec![] as Vec<i32>);
1552 }
1553
1554 #[test]
1556 fn wilt_empty() {
1557 let res = wilt::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1558 assert_eq!(res, Some((vec![], vec![])));
1559 }
1560
1561 #[test]
1563 fn wither_empty() {
1564 let res = wither::<VecBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), vec![]);
1565 assert_eq!(res, Some(vec![]));
1566 }
1567}