1use crate::{
6 Apply,
7 brands::{OptionBrand, VecBrand},
8 classes::{
9 Applicative, ApplyFirst, ApplySecond, CloneableFn, Compactable, Filterable, Foldable,
10 Functor, Lift, Monoid, ParFoldable, Pointed, Semiapplicative, Semigroup, Semimonad,
11 SendCloneableFn, Traversable, Witherable,
12 },
13 impl_kind,
14 kinds::*,
15 types::Pair,
16};
17use fp_macros::{doc_params, doc_type_params, hm_signature};
18#[cfg(feature = "rayon")]
19use rayon::prelude::*;
20
21impl_kind! {
22 for VecBrand {
23 type Of<'a, A: 'a>: 'a = Vec<A>;
24 }
25}
26
27impl VecBrand {
28 #[hm_signature]
35 #[doc_type_params("The type of the elements in the vector.")]
39 #[doc_params("A value to prepend to the vector.", "A vector to prepend the value to.")]
43 pub fn construct<A>(
63 head: A,
64 tail: Vec<A>,
65 ) -> Vec<A>
66 where
67 A: Clone,
68 {
69 [vec![head], tail].concat()
70 }
71
72 #[hm_signature]
79 #[doc_type_params("The type of the elements in the vector.")]
83 #[doc_params("The vector slice to deconstruct.")]
87 pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
106 where
107 A: Clone,
108 {
109 match slice {
110 [] => None,
111 [head, tail @ ..] => Some((head.clone(), tail.to_vec())),
112 }
113 }
114}
115
116impl Functor for VecBrand {
117 #[hm_signature(Functor)]
124 #[doc_type_params(
128 "The lifetime of the elements.",
129 "The type of the elements in the vector.",
130 "The type of the elements in the resulting vector.",
131 "The type of the function to apply."
132 )]
133 #[doc_params("The function to apply to each element.", "The vector to map over.")]
137 fn map<'a, A: 'a, B: 'a, Func>(
150 func: Func,
151 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
152 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
153 where
154 Func: Fn(A) -> B + 'a,
155 {
156 fa.into_iter().map(func).collect()
157 }
158}
159
160impl Lift for VecBrand {
161 #[hm_signature(Lift)]
168 #[doc_type_params(
172 "The lifetime of the elements.",
173 "The type of the elements in the first vector.",
174 "The type of the elements in the second vector.",
175 "The type of the elements in the resulting vector.",
176 "The type of the binary function."
177 )]
178 #[doc_params("The binary function to apply.", "The first vector.", "The second vector.")]
182 fn lift2<'a, A, B, C, Func>(
198 func: Func,
199 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
200 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
201 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
202 where
203 Func: Fn(A, B) -> C + 'a,
204 A: Clone + 'a,
205 B: Clone + 'a,
206 C: 'a,
207 {
208 fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
209 }
210}
211
212impl Pointed for VecBrand {
213 #[hm_signature(Pointed)]
220 #[doc_type_params("The lifetime of the value.", "The type of the value to wrap.")]
224 #[doc_params("The value to wrap.")]
228 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
242 vec![a]
243 }
244}
245
246impl ApplyFirst for VecBrand {}
247impl ApplySecond for VecBrand {}
248
249impl Semiapplicative for VecBrand {
250 #[hm_signature(Semiapplicative)]
257 #[doc_type_params(
261 "The lifetime of the values.",
262 "The brand of the cloneable function wrapper.",
263 "The type of the input values.",
264 "The type of the output values."
265 )]
266 #[doc_params("The vector containing the functions.", "The vector containing the values.")]
270 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
287 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
288 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
289 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
290 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
291 }
292}
293
294impl Semimonad for VecBrand {
295 #[hm_signature(Semimonad)]
302 #[doc_type_params(
306 "The lifetime of the elements.",
307 "The type of the elements in the input vector.",
308 "The type of the elements in the output vector.",
309 "The type of the function to apply."
310 )]
311 #[doc_params("The first vector.", "The function to apply to each element, returning a vector.")]
315 fn bind<'a, A: 'a, B: 'a, Func>(
332 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
333 func: Func,
334 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
335 where
336 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
337 {
338 ma.into_iter().flat_map(func).collect()
339 }
340}
341
342impl Foldable for VecBrand {
343 #[hm_signature(Foldable)]
350 #[doc_type_params(
354 "The lifetime of the elements.",
355 "The brand of the cloneable function to use.",
356 "The type of the elements in the vector.",
357 "The type of the accumulator.",
358 "The type of the folding function."
359 )]
360 #[doc_params("The folding function.", "The initial value.", "The vector to fold.")]
364 fn fold_right<'a, FnBrand, A: 'a, B: 'a, Func>(
377 func: Func,
378 initial: B,
379 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
380 ) -> B
381 where
382 Func: Fn(A, B) -> B + 'a,
383 FnBrand: CloneableFn + 'a,
384 {
385 fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
386 }
387
388 #[hm_signature(Foldable)]
395 #[doc_type_params(
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 accumulator.",
403 "The type of the folding function."
404 )]
405 #[doc_params(
409 "The function to apply to the accumulator and each element.",
410 "The initial value of the accumulator.",
411 "The vector to fold."
412 )]
413 fn fold_left<'a, FnBrand, A: 'a, B: 'a, Func>(
426 func: Func,
427 initial: B,
428 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
429 ) -> B
430 where
431 Func: Fn(B, A) -> B + 'a,
432 FnBrand: CloneableFn + 'a,
433 {
434 fa.into_iter().fold(initial, func)
435 }
436
437 #[hm_signature(Foldable)]
444 #[doc_type_params(
448 "The lifetime of the elements.",
449 "The brand of the cloneable function to use.",
450 "The type of the elements in the vector.",
451 "The type of the monoid.",
452 "The type of the mapping function."
453 )]
454 #[doc_params("The mapping function.", "The vector to fold.")]
458 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
474 func: Func,
475 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
476 ) -> M
477 where
478 M: Monoid + 'a,
479 Func: Fn(A) -> M + 'a,
480 FnBrand: CloneableFn + 'a,
481 {
482 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
483 }
484}
485
486impl Traversable for VecBrand {
487 #[hm_signature(Traversable)]
494 #[doc_type_params(
498 "The lifetime of the elements.",
499 "The type of the elements in the traversable structure.",
500 "The type of the elements in the resulting traversable structure.",
501 "The applicative context.",
502 "The type of the function to apply."
503 )]
504 #[doc_params(
508 "The function to apply to each element, returning a value in an applicative context.",
509 "The vector to traverse."
510 )]
511 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
528 func: Func,
529 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
530 ) -> 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>)>)
531 where
532 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
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 {
536 let len = ta.len();
537 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
538 F::lift2(
539 |mut v, b| {
540 v.push(b);
541 v
542 },
543 acc,
544 func(x),
545 )
546 })
547 }
548 #[hm_signature(Traversable)]
555 #[doc_type_params(
559 "The lifetime of the elements.",
560 "The type of the elements in the traversable structure.",
561 "The applicative context."
562 )]
563 #[doc_params("The vector containing the applicative values.")]
567 fn sequence<'a, A: 'a + Clone, F: Applicative>(
584 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>)>)
585 ) -> 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>)>)
586 where
587 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
588 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
589 {
590 let len = ta.len();
591 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
592 F::lift2(
593 |mut v, a| {
594 v.push(a);
595 v
596 },
597 acc,
598 x,
599 )
600 })
601 }
602}
603
604impl<A: Clone> Semigroup for Vec<A> {
605 #[hm_signature(Semigroup)]
612 #[doc_params("The first vector.", "The second vector.")]
620 fn append(
633 a: Self,
634 b: Self,
635 ) -> Self {
636 [a, b].concat()
637 }
638}
639
640impl<A: Clone> Monoid for Vec<A> {
641 #[hm_signature(Monoid)]
648 fn empty() -> Self {
665 Vec::new()
666 }
667}
668
669impl ParFoldable for VecBrand {
670 #[hm_signature(ParFoldable)]
679 #[doc_type_params(
683 "The lifetime of the elements.",
684 "The brand of the cloneable function wrapper.",
685 "The element type.",
686 "The monoid type."
687 )]
688 #[doc_params(
692 "The thread-safe function to map each element to a monoid.",
693 "The vector to fold."
694 )]
695 fn par_fold_map<'a, FnBrand, A, M>(
710 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
711 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
712 ) -> M
713 where
714 FnBrand: 'a + SendCloneableFn,
715 A: 'a + Clone + Send + Sync,
716 M: Monoid + Send + Sync + 'a,
717 {
718 #[cfg(feature = "rayon")]
719 {
720 fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
721 }
722 #[cfg(not(feature = "rayon"))]
723 {
724 #[allow(clippy::redundant_closure)]
725 fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
726 }
727 }
728}
729
730impl Compactable for VecBrand {
731 #[hm_signature(Compactable)]
738 #[doc_type_params("The lifetime of the elements.", "The type of the elements.")]
742 #[doc_params("The vector of options.")]
746 fn compact<'a, A: 'a>(
762 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
763 'a,
764 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
765 >)
766 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
767 fa.into_iter().flatten().collect()
768 }
769
770 #[hm_signature(Compactable)]
777 #[doc_type_params(
781 "The lifetime of the elements.",
782 "The type of the success value.",
783 "The type of the error value."
784 )]
785 #[doc_params("The vector of results.")]
789 fn separate<'a, O: 'a, E: 'a>(
805 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
806 ) -> Pair<
807 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
808 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
809 > {
810 let mut oks = Vec::new();
811 let mut errs = Vec::new();
812 for result in fa {
813 match result {
814 Ok(o) => oks.push(o),
815 Err(e) => errs.push(e),
816 }
817 }
818 Pair(oks, errs)
819 }
820}
821
822impl Filterable for VecBrand {
823 #[hm_signature(Filterable)]
830 #[doc_type_params(
834 "The lifetime of the elements.",
835 "The type of the input value.",
836 "The type of the success value.",
837 "The type of the error value.",
838 "The type of the function to apply."
839 )]
840 #[doc_params("The function to apply.", "The vector to partition.")]
844 fn partition_map<'a, A: 'a, O: 'a, E: 'a, Func>(
860 func: Func,
861 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
862 ) -> Pair<
863 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
864 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
865 >
866 where
867 Func: Fn(A) -> Result<O, E> + 'a,
868 {
869 let mut oks = Vec::new();
870 let mut errs = Vec::new();
871 for a in fa {
872 match func(a) {
873 Ok(o) => oks.push(o),
874 Err(e) => errs.push(e),
875 }
876 }
877 Pair(oks, errs)
878 }
879 #[hm_signature(Filterable)]
886 #[doc_type_params(
890 "The lifetime of the elements.",
891 "The type of the elements.",
892 "The type of the predicate."
893 )]
894 #[doc_params("The predicate.", "The vector to partition.")]
898 fn partition<'a, A: 'a + Clone, Func>(
914 func: Func,
915 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
916 ) -> Pair<
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 where
921 Func: Fn(A) -> bool + 'a,
922 {
923 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
924 fa.into_iter().partition(|a| func(a.clone()));
925 Pair(satisfied, not_satisfied)
926 }
927
928 #[hm_signature(Filterable)]
935 #[doc_type_params(
939 "The lifetime of the elements.",
940 "The type of the input value.",
941 "The type of the result of applying the function.",
942 "The type of the function to apply."
943 )]
944 #[doc_params("The function to apply.", "The vector to filter and map.")]
948 fn filter_map<'a, A: 'a, B: 'a, Func>(
964 func: Func,
965 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
966 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
967 where
968 Func: Fn(A) -> Option<B> + 'a,
969 {
970 fa.into_iter().filter_map(func).collect()
971 }
972
973 #[hm_signature(Filterable)]
980 #[doc_type_params(
984 "The lifetime of the elements.",
985 "The type of the elements.",
986 "The type of the predicate."
987 )]
988 #[doc_params("The predicate.", "The vector to filter.")]
992 fn filter<'a, A: 'a + Clone, Func>(
1008 func: Func,
1009 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1010 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
1011 where
1012 Func: Fn(A) -> bool + 'a,
1013 {
1014 fa.into_iter().filter(|a| func(a.clone())).collect()
1015 }
1016}
1017
1018impl Witherable for VecBrand {
1019 #[hm_signature(Witherable)]
1026 #[doc_type_params(
1030 "The lifetime of the elements.",
1031 "The applicative context.",
1032 "The type of the input value.",
1033 "The type of the success value.",
1034 "The type of the error value.",
1035 "The type of the function to apply."
1036 )]
1037 #[doc_params("The function to apply.", "The vector to partition.")]
1041 fn wilt<'a, M: Applicative, A: 'a + Clone, O: 'a + Clone, E: 'a + Clone, Func>(
1056 func: Func,
1057 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1058 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1059 'a,
1060 Pair<
1061 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1062 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1063 >,
1064 >)
1065 where
1066 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
1067 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1068 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1069 {
1070 ta.into_iter().fold(M::pure(Pair(Vec::new(), Vec::new())), |acc, x| {
1071 M::lift2(
1072 |mut pair, res| {
1073 match res {
1074 Ok(o) => pair.0.push(o),
1075 Err(e) => pair.1.push(e),
1076 }
1077 pair
1078 },
1079 acc,
1080 func(x),
1081 )
1082 })
1083 }
1084
1085 #[hm_signature(Witherable)]
1092 #[doc_type_params(
1096 "The lifetime of the values.",
1097 "The applicative context.",
1098 "The type of the elements in the input structure.",
1099 "The type of the result of applying the function.",
1100 "The type of the function to apply."
1101 )]
1102 #[doc_params(
1106 "The function to apply to each element, returning an `Option` in an applicative context.",
1107 "The vector to filter and map."
1108 )]
1109 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone, Func>(
1125 func: Func,
1126 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1127 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1128 'a,
1129 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1130 >)
1131 where
1132 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1133 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1134 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1135 {
1136 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1137 M::lift2(
1138 |mut v, opt_b| {
1139 if let Some(b) = opt_b {
1140 v.push(b);
1141 }
1142 v
1143 },
1144 acc,
1145 func(x),
1146 )
1147 })
1148 }
1149}
1150
1151#[cfg(test)]
1152mod tests {
1153 use super::*;
1154 use crate::{brands::*, functions::*};
1155 use quickcheck_macros::quickcheck;
1156
1157 #[quickcheck]
1161 fn functor_identity(x: Vec<i32>) -> bool {
1162 map::<VecBrand, _, _, _>(identity, x.clone()) == x
1163 }
1164
1165 #[quickcheck]
1167 fn functor_composition(x: Vec<i32>) -> bool {
1168 let f = |x: i32| x.wrapping_add(1);
1169 let g = |x: i32| x.wrapping_mul(2);
1170 map::<VecBrand, _, _, _>(compose(f, g), x.clone())
1171 == map::<VecBrand, _, _, _>(f, map::<VecBrand, _, _, _>(g, x))
1172 }
1173
1174 #[quickcheck]
1178 fn applicative_identity(v: Vec<i32>) -> bool {
1179 apply::<RcFnBrand, VecBrand, _, _>(
1180 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1181 v.clone(),
1182 ) == v
1183 }
1184
1185 #[quickcheck]
1187 fn applicative_homomorphism(x: i32) -> bool {
1188 let f = |x: i32| x.wrapping_mul(2);
1189 apply::<RcFnBrand, VecBrand, _, _>(
1190 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1191 pure::<VecBrand, _>(x),
1192 ) == pure::<VecBrand, _>(f(x))
1193 }
1194
1195 #[quickcheck]
1197 fn applicative_composition(
1198 w: Vec<i32>,
1199 u_seeds: Vec<i32>,
1200 v_seeds: Vec<i32>,
1201 ) -> bool {
1202 let u_fns: Vec<_> = u_seeds
1203 .iter()
1204 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1205 .collect();
1206 let v_fns: Vec<_> = v_seeds
1207 .iter()
1208 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1209 .collect();
1210
1211 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1213 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1214
1215 let uv_fns: Vec<_> = u_fns
1219 .iter()
1220 .flat_map(|uf| {
1221 v_fns.iter().map(move |vf| {
1222 let uf = uf.clone();
1223 let vf = vf.clone();
1224 <RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1225 })
1226 })
1227 .collect();
1228
1229 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1230
1231 lhs == rhs
1232 }
1233
1234 #[quickcheck]
1236 fn applicative_interchange(y: i32) -> bool {
1237 let f = |x: i32| x.wrapping_mul(2);
1239 let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1240
1241 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1242
1243 let rhs_fn =
1244 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1245 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1246
1247 lhs == rhs
1248 }
1249
1250 #[quickcheck]
1254 fn semigroup_associativity(
1255 a: Vec<i32>,
1256 b: Vec<i32>,
1257 c: Vec<i32>,
1258 ) -> bool {
1259 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1260 }
1261
1262 #[quickcheck]
1266 fn monoid_left_identity(a: Vec<i32>) -> bool {
1267 append(empty::<Vec<i32>>(), a.clone()) == a
1268 }
1269
1270 #[quickcheck]
1272 fn monoid_right_identity(a: Vec<i32>) -> bool {
1273 append(a.clone(), empty::<Vec<i32>>()) == a
1274 }
1275
1276 #[quickcheck]
1280 fn monad_left_identity(a: i32) -> bool {
1281 let f = |x: i32| vec![x.wrapping_mul(2)];
1282 bind::<VecBrand, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1283 }
1284
1285 #[quickcheck]
1287 fn monad_right_identity(m: Vec<i32>) -> bool {
1288 bind::<VecBrand, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
1289 }
1290
1291 #[quickcheck]
1293 fn monad_associativity(m: Vec<i32>) -> bool {
1294 let f = |x: i32| vec![x.wrapping_mul(2)];
1295 let g = |x: i32| vec![x.wrapping_add(1)];
1296 bind::<VecBrand, _, _, _>(bind::<VecBrand, _, _, _>(m.clone(), f), g)
1297 == bind::<VecBrand, _, _, _>(m, |x| bind::<VecBrand, _, _, _>(f(x), g))
1298 }
1299
1300 #[test]
1304 fn map_empty() {
1305 assert_eq!(
1306 map::<VecBrand, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
1307 vec![] as Vec<i32>
1308 );
1309 }
1310
1311 #[test]
1313 fn bind_empty() {
1314 assert_eq!(
1315 bind::<VecBrand, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1316 vec![] as Vec<i32>
1317 );
1318 }
1319
1320 #[test]
1322 fn bind_returning_empty() {
1323 assert_eq!(
1324 bind::<VecBrand, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1325 vec![] as Vec<i32>
1326 );
1327 }
1328
1329 #[test]
1331 fn fold_right_empty() {
1332 assert_eq!(
1333 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _, _>(
1334 |x: i32, acc| x + acc,
1335 0,
1336 vec![]
1337 ),
1338 0
1339 );
1340 }
1341
1342 #[test]
1344 fn fold_left_empty() {
1345 assert_eq!(
1346 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _, _>(
1347 |acc, x: i32| acc + x,
1348 0,
1349 vec![]
1350 ),
1351 0
1352 );
1353 }
1354
1355 #[test]
1357 fn traverse_empty() {
1358 use crate::brands::OptionBrand;
1359 assert_eq!(
1360 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand, _>(
1361 |x: i32| Some(x + 1),
1362 vec![]
1363 ),
1364 Some(vec![])
1365 );
1366 }
1367
1368 #[test]
1370 fn traverse_returning_empty() {
1371 use crate::brands::OptionBrand;
1372 assert_eq!(
1373 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand, _>(
1374 |_: i32| None::<i32>,
1375 vec![1, 2, 3]
1376 ),
1377 None
1378 );
1379 }
1380
1381 #[test]
1383 fn construct_empty_tail() {
1384 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1385 }
1386
1387 #[test]
1389 fn deconstruct_empty() {
1390 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1391 }
1392
1393 #[test]
1397 fn par_fold_map_empty() {
1398 let v: Vec<i32> = vec![];
1399 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1400 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1401 }
1402
1403 #[test]
1405 fn par_fold_map_single() {
1406 let v = vec![1];
1407 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1408 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1409 }
1410
1411 #[test]
1413 fn par_fold_map_multiple() {
1414 let v = vec![1, 2, 3];
1415 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1416 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1417 }
1418
1419 #[test]
1421 fn par_fold_right_multiple() {
1422 let v = vec![1, 2, 3];
1423 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1424 assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1425 }
1426
1427 #[quickcheck]
1431 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1432 filter_map::<VecBrand, _, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1433 }
1434
1435 #[quickcheck]
1437 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1438 filter_map::<VecBrand, _, _, _>(Some, x.clone()) == x
1439 }
1440
1441 #[quickcheck]
1443 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1444 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1445 let l = |i: i32| if i > 5 { Some(i) } else { None };
1446 let composed = |i| bind::<OptionBrand, _, _, _>(r(i), l);
1447
1448 filter_map::<VecBrand, _, _, _>(composed, x.clone())
1449 == filter_map::<VecBrand, _, _, _>(l, filter_map::<VecBrand, _, _, _>(r, x))
1450 }
1451
1452 #[quickcheck]
1454 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1455 let p = |i: i32| i % 2 == 0;
1456 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1457
1458 filter::<VecBrand, _, _>(p, x.clone()) == filter_map::<VecBrand, _, _, _>(maybe_bool, x)
1459 }
1460
1461 #[quickcheck]
1463 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1464 partition_map::<VecBrand, _, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1465 }
1466
1467 #[quickcheck]
1469 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1470 let Pair(oks, _) = partition_map::<VecBrand, _, _, _, _>(Ok::<_, i32>, x.clone());
1471 oks == x
1472 }
1473
1474 #[quickcheck]
1476 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1477 let Pair(_, errs) = partition_map::<VecBrand, _, _, _, _>(Err::<i32, _>, x.clone());
1478 errs == x
1479 }
1480
1481 #[quickcheck]
1483 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1484 let p = |i: i32| i % 2 == 0;
1485 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1486
1487 let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(p, x.clone());
1488 let Pair(oks, errs) = partition_map::<VecBrand, _, _, _, _>(either_bool, x);
1489
1490 satisfied == oks && not_satisfied == errs
1491 }
1492
1493 #[quickcheck]
1497 fn witherable_identity(x: Vec<i32>) -> bool {
1498 wither::<VecBrand, OptionBrand, _, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1499 }
1500
1501 #[quickcheck]
1503 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1504 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1505
1506 let lhs = wilt::<VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
1507 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1508 |res| separate::<VecBrand, _, _>(res),
1509 traverse::<VecBrand, _, _, OptionBrand, _>(p, x),
1510 );
1511
1512 lhs == rhs
1513 }
1514
1515 #[quickcheck]
1517 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1518 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1519
1520 let lhs = wither::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1521 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1522 |opt| compact::<VecBrand, _>(opt),
1523 traverse::<VecBrand, _, _, OptionBrand, _>(p, x),
1524 );
1525
1526 lhs == rhs
1527 }
1528
1529 #[test]
1533 fn compact_empty() {
1534 assert_eq!(compact::<VecBrand, _>(vec![] as Vec<Option<i32>>), vec![]);
1535 }
1536
1537 #[test]
1539 fn compact_with_none() {
1540 assert_eq!(compact::<VecBrand, _>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1541 }
1542
1543 #[test]
1545 fn separate_empty() {
1546 let Pair(oks, errs) = separate::<VecBrand, _, _>(vec![] as Vec<Result<i32, i32>>);
1547 assert_eq!(oks, vec![]);
1548 assert_eq!(errs, vec![]);
1549 }
1550
1551 #[test]
1553 fn separate_mixed() {
1554 let Pair(oks, errs) = separate::<VecBrand, _, _>(vec![Ok(1), Err(2), Ok(3)]);
1555 assert_eq!(oks, vec![1, 3]);
1556 assert_eq!(errs, vec![2]);
1557 }
1558
1559 #[test]
1561 fn partition_map_empty() {
1562 let Pair(oks, errs) =
1563 partition_map::<VecBrand, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1564 assert_eq!(oks, vec![]);
1565 assert_eq!(errs, vec![]);
1566 }
1567
1568 #[test]
1570 fn partition_empty() {
1571 let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(|x: i32| x > 0, vec![]);
1572 assert_eq!(satisfied, vec![]);
1573 assert_eq!(not_satisfied, vec![]);
1574 }
1575
1576 #[test]
1578 fn filter_map_empty() {
1579 assert_eq!(filter_map::<VecBrand, _, _, _>(|x: i32| Some(x), vec![]), vec![]);
1580 }
1581
1582 #[test]
1584 fn filter_empty() {
1585 assert_eq!(filter::<VecBrand, _, _>(|x: i32| x > 0, vec![]), vec![]);
1586 }
1587
1588 #[test]
1590 fn wilt_empty() {
1591 let res =
1592 wilt::<VecBrand, OptionBrand, _, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1593 assert_eq!(res, Some(Pair(vec![], vec![])));
1594 }
1595
1596 #[test]
1598 fn wither_empty() {
1599 let res = wither::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Some(x)), vec![]);
1600 assert_eq!(res, Some(vec![]));
1601 }
1602}