1#[fp_macros::document_module]
6mod inner {
7 use crate::{
8 Apply,
9 brands::{OptionBrand, VecBrand},
10 classes::{
11 Applicative, ApplyFirst, ApplySecond, CloneableFn, Compactable, Filterable, Foldable,
12 Functor, Lift, Monoid, ParFoldable, Pointed, Semiapplicative, Semigroup, Semimonad,
13 SendCloneableFn, Traversable, Witherable,
14 },
15 impl_kind,
16 kinds::*,
17 };
18 use fp_macros::document_parameters;
19 #[cfg(feature = "rayon")]
20 use rayon::prelude::*;
21
22 impl_kind! {
23 for VecBrand {
24 type Of<'a, A: 'a>: 'a = Vec<A>;
25 }
26 }
27
28 impl VecBrand {
29 #[document_signature]
36 #[document_type_parameters("The type of the elements in the vector.")]
40 #[document_parameters(
44 "A value to prepend to the vector.",
45 "A vector to prepend the value to."
46 )]
47 pub fn construct<A>(
67 head: A,
68 tail: Vec<A>,
69 ) -> Vec<A>
70 where
71 A: Clone,
72 {
73 [vec![head], tail].concat()
74 }
75
76 #[document_signature]
83 #[document_type_parameters("The type of the elements in the vector.")]
87 #[document_parameters("The vector slice to deconstruct.")]
91 pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
110 where
111 A: Clone,
112 {
113 match slice {
114 [] => None,
115 [head, tail @ ..] => Some((head.clone(), tail.to_vec())),
116 }
117 }
118 }
119
120 impl Functor for VecBrand {
121 #[document_signature]
128 #[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 "The type of the function to apply."
136 )]
137 #[document_parameters("The function to apply to each element.", "The vector to map over.")]
141 fn map<'a, A: 'a, B: 'a, Func>(
154 func: Func,
155 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
156 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
157 where
158 Func: Fn(A) -> B + 'a,
159 {
160 fa.into_iter().map(func).collect()
161 }
162 }
163
164 impl Lift for VecBrand {
165 #[document_signature]
172 #[document_type_parameters(
176 "The lifetime of the elements.",
177 "The type of the elements in the first vector.",
178 "The type of the elements in the second vector.",
179 "The type of the elements in the resulting vector.",
180 "The type of the binary function."
181 )]
182 #[document_parameters(
186 "The binary function to apply.",
187 "The first vector.",
188 "The second vector."
189 )]
190 fn lift2<'a, A, B, C, Func>(
206 func: Func,
207 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
208 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
209 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
210 where
211 Func: Fn(A, B) -> C + 'a,
212 A: Clone + 'a,
213 B: Clone + 'a,
214 C: 'a,
215 {
216 fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
217 }
218 }
219
220 impl Pointed for VecBrand {
221 #[document_signature]
228 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
232 #[document_parameters("The value to wrap.")]
236 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
250 vec![a]
251 }
252 }
253
254 impl ApplyFirst for VecBrand {}
255 impl ApplySecond for VecBrand {}
256
257 impl Semiapplicative for VecBrand {
258 #[document_signature]
265 #[document_type_parameters(
269 "The lifetime of the values.",
270 "The brand of the cloneable function wrapper.",
271 "The type of the input values.",
272 "The type of the output values."
273 )]
274 #[document_parameters(
278 "The vector containing the functions.",
279 "The vector containing the values."
280 )]
281 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
298 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
299 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
300 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
301 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
302 }
303 }
304
305 impl Semimonad for VecBrand {
306 #[document_signature]
313 #[document_type_parameters(
317 "The lifetime of the elements.",
318 "The type of the elements in the input vector.",
319 "The type of the elements in the output vector.",
320 "The type of the function to apply."
321 )]
322 #[document_parameters(
326 "The first vector.",
327 "The function to apply to each element, returning a vector."
328 )]
329 fn bind<'a, A: 'a, B: 'a, Func>(
346 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
347 func: Func,
348 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
349 where
350 Func: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
351 {
352 ma.into_iter().flat_map(func).collect()
353 }
354 }
355
356 impl Foldable for VecBrand {
357 #[document_signature]
364 #[document_type_parameters(
368 "The lifetime of the elements.",
369 "The brand of the cloneable function to use.",
370 "The type of the elements in the vector.",
371 "The type of the accumulator.",
372 "The type of the folding function."
373 )]
374 #[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
378 fn fold_right<'a, FnBrand, A: 'a, B: 'a, Func>(
391 func: Func,
392 initial: B,
393 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
394 ) -> B
395 where
396 Func: Fn(A, B) -> B + 'a,
397 FnBrand: CloneableFn + 'a,
398 {
399 fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
400 }
401
402 #[document_signature]
409 #[document_type_parameters(
413 "The lifetime of the elements.",
414 "The brand of the cloneable function to use.",
415 "The type of the elements in the vector.",
416 "The type of the accumulator.",
417 "The type of the folding function."
418 )]
419 #[document_parameters(
423 "The function to apply to the accumulator and each element.",
424 "The initial value of the accumulator.",
425 "The vector to fold."
426 )]
427 fn fold_left<'a, FnBrand, A: 'a, B: 'a, Func>(
440 func: Func,
441 initial: B,
442 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
443 ) -> B
444 where
445 Func: Fn(B, A) -> B + 'a,
446 FnBrand: CloneableFn + 'a,
447 {
448 fa.into_iter().fold(initial, func)
449 }
450
451 #[document_signature]
458 #[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 "The type of the mapping function."
467 )]
468 #[document_parameters("The mapping function.", "The vector to fold.")]
472 fn fold_map<'a, FnBrand, A: 'a, M, Func>(
488 func: Func,
489 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
490 ) -> M
491 where
492 M: Monoid + 'a,
493 Func: Fn(A) -> M + 'a,
494 FnBrand: CloneableFn + 'a,
495 {
496 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
497 }
498 }
499
500 impl Traversable for VecBrand {
501 #[document_signature]
508 #[document_type_parameters(
512 "The lifetime of the elements.",
513 "The type of the elements in the traversable structure.",
514 "The type of the elements in the resulting traversable structure.",
515 "The applicative context.",
516 "The type of the function to apply."
517 )]
518 #[document_parameters(
522 "The function to apply to each element, returning a value in an applicative context.",
523 "The vector to traverse."
524 )]
525 fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative, Func>(
542 func: Func,
543 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
544 ) -> 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>)>)
545 where
546 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
547 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
548 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
549 {
550 let len = ta.len();
551 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
552 F::lift2(
553 |mut v, b| {
554 v.push(b);
555 v
556 },
557 acc,
558 func(x),
559 )
560 })
561 }
562 #[document_signature]
569 #[document_type_parameters(
573 "The lifetime of the elements.",
574 "The type of the elements in the traversable structure.",
575 "The applicative context."
576 )]
577 #[document_parameters("The vector containing the applicative values.")]
581 fn sequence<'a, A: 'a + Clone, F: Applicative>(
598 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>)>)
599 ) -> 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>)>)
600 where
601 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
602 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
603 {
604 let len = ta.len();
605 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
606 F::lift2(
607 |mut v, a| {
608 v.push(a);
609 v
610 },
611 acc,
612 x,
613 )
614 })
615 }
616 }
617
618 #[document_type_parameters("The type of the elements in the vector.")]
621 impl<A: Clone> Semigroup for Vec<A> {
622 #[document_signature]
629 #[document_parameters("The first vector.", "The second vector.")]
633 fn append(
646 a: Self,
647 b: Self,
648 ) -> Self {
649 [a, b].concat()
650 }
651 }
652
653 #[document_type_parameters("The type of the elements in the vector.")]
656 impl<A: Clone> Monoid for Vec<A> {
657 #[document_signature]
664 fn empty() -> Self {
677 Vec::new()
678 }
679 }
680
681 impl ParFoldable for VecBrand {
682 #[document_signature]
691 #[document_type_parameters(
695 "The lifetime of the elements.",
696 "The brand of the cloneable function wrapper.",
697 "The element type.",
698 "The monoid type."
699 )]
700 #[document_parameters(
704 "The thread-safe function to map each element to a monoid.",
705 "The vector to fold."
706 )]
707 fn par_fold_map<'a, FnBrand, A, M>(
722 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
723 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
724 ) -> M
725 where
726 FnBrand: 'a + SendCloneableFn,
727 A: 'a + Clone + Send + Sync,
728 M: Monoid + Send + Sync + 'a,
729 {
730 #[cfg(feature = "rayon")]
731 {
732 fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
733 }
734 #[cfg(not(feature = "rayon"))]
735 {
736 #[allow(clippy::redundant_closure)] fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
738 }
739 }
740 }
741
742 impl Compactable for VecBrand {
743 #[document_signature]
750 #[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
754 #[document_parameters("The vector of options.")]
758 fn compact<'a, A: 'a>(
774 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
775 'a,
776 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
777 >)
778 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
779 fa.into_iter().flatten().collect()
780 }
781
782 #[document_signature]
789 #[document_type_parameters(
793 "The lifetime of the elements.",
794 "The type of the error value.",
795 "The type of the success value."
796 )]
797 #[document_parameters("The vector of results.")]
801 fn separate<'a, E: 'a, O: 'a>(
817 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
818 ) -> (
819 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
820 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
821 ) {
822 let mut oks = Vec::new();
823 let mut errs = Vec::new();
824 for result in fa {
825 match result {
826 Ok(o) => oks.push(o),
827 Err(e) => errs.push(e),
828 }
829 }
830 (errs, oks)
831 }
832 }
833
834 impl Filterable for VecBrand {
835 #[document_signature]
842 #[document_type_parameters(
846 "The lifetime of the elements.",
847 "The type of the input value.",
848 "The type of the error value.",
849 "The type of the success value.",
850 "The type of the function to apply."
851 )]
852 #[document_parameters("The function to apply.", "The vector to partition.")]
856 fn partition_map<'a, A: 'a, E: 'a, O: 'a, Func>(
872 func: Func,
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 where
879 Func: Fn(A) -> Result<O, E> + 'a,
880 {
881 let mut oks = Vec::new();
882 let mut errs = Vec::new();
883 for a in fa {
884 match func(a) {
885 Ok(o) => oks.push(o),
886 Err(e) => errs.push(e),
887 }
888 }
889 (errs, oks)
890 }
891 #[document_signature]
898 #[document_type_parameters(
902 "The lifetime of the elements.",
903 "The type of the elements.",
904 "The type of the predicate."
905 )]
906 #[document_parameters("The predicate.", "The vector to partition.")]
910 fn partition<'a, A: 'a + Clone, Func>(
926 func: Func,
927 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
928 ) -> (
929 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
930 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
931 )
932 where
933 Func: Fn(A) -> bool + 'a,
934 {
935 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
936 fa.into_iter().partition(|a| func(a.clone()));
937 (not_satisfied, satisfied)
938 }
939
940 #[document_signature]
947 #[document_type_parameters(
951 "The lifetime of the elements.",
952 "The type of the input value.",
953 "The type of the result of applying the function.",
954 "The type of the function to apply."
955 )]
956 #[document_parameters("The function to apply.", "The vector to filter and map.")]
960 fn filter_map<'a, A: 'a, B: 'a, Func>(
976 func: Func,
977 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
978 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
979 where
980 Func: Fn(A) -> Option<B> + 'a,
981 {
982 fa.into_iter().filter_map(func).collect()
983 }
984
985 #[document_signature]
992 #[document_type_parameters(
996 "The lifetime of the elements.",
997 "The type of the elements.",
998 "The type of the predicate."
999 )]
1000 #[document_parameters("The predicate.", "The vector to filter.")]
1004 fn filter<'a, A: 'a + Clone, Func>(
1020 func: Func,
1021 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1022 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
1023 where
1024 Func: Fn(A) -> bool + 'a,
1025 {
1026 fa.into_iter().filter(|a| func(a.clone())).collect()
1027 }
1028 }
1029
1030 impl Witherable for VecBrand {
1031 #[document_signature]
1038 #[document_type_parameters(
1042 "The lifetime of the elements.",
1043 "The applicative context.",
1044 "The type of the input value.",
1045 "The type of the error value.",
1046 "The type of the success value.",
1047 "The type of the function to apply."
1048 )]
1049 #[document_parameters("The function to apply.", "The vector to partition.")]
1053 fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone, Func>(
1068 func: Func,
1069 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1070 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1071 'a,
1072 (
1073 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1074 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1075 ),
1076 >)
1077 where
1078 Func:
1079 Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
1080 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1081 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1082 {
1083 ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
1084 M::lift2(
1085 |mut pair, res| {
1086 match res {
1087 Ok(o) => pair.1.push(o),
1088 Err(e) => pair.0.push(e),
1089 }
1090 pair
1091 },
1092 acc,
1093 func(x),
1094 )
1095 })
1096 }
1097
1098 #[document_signature]
1105 #[document_type_parameters(
1109 "The lifetime of the values.",
1110 "The applicative context.",
1111 "The type of the elements in the input structure.",
1112 "The type of the result of applying the function.",
1113 "The type of the function to apply."
1114 )]
1115 #[document_parameters(
1119 "The function to apply to each element, returning an `Option` in an applicative context.",
1120 "The vector to filter and map."
1121 )]
1122 fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone, Func>(
1138 func: Func,
1139 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1140 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1141 'a,
1142 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1143 >)
1144 where
1145 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1146 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1147 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1148 {
1149 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1150 M::lift2(
1151 |mut v, opt_b| {
1152 if let Some(b) = opt_b {
1153 v.push(b);
1154 }
1155 v
1156 },
1157 acc,
1158 func(x),
1159 )
1160 })
1161 }
1162 }
1163}
1164
1165#[cfg(test)]
1166mod tests {
1167
1168 use crate::{brands::*, classes::CloneableFn, functions::*};
1169 use quickcheck_macros::quickcheck;
1170
1171 #[quickcheck]
1175 fn functor_identity(x: Vec<i32>) -> bool {
1176 map::<VecBrand, _, _, _>(identity, x.clone()) == x
1177 }
1178
1179 #[quickcheck]
1181 fn functor_composition(x: Vec<i32>) -> bool {
1182 let f = |x: i32| x.wrapping_add(1);
1183 let g = |x: i32| x.wrapping_mul(2);
1184 map::<VecBrand, _, _, _>(compose(f, g), x.clone())
1185 == map::<VecBrand, _, _, _>(f, map::<VecBrand, _, _, _>(g, x))
1186 }
1187
1188 #[quickcheck]
1192 fn applicative_identity(v: Vec<i32>) -> bool {
1193 apply::<RcFnBrand, VecBrand, _, _>(
1194 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1195 v.clone(),
1196 ) == v
1197 }
1198
1199 #[quickcheck]
1201 fn applicative_homomorphism(x: i32) -> bool {
1202 let f = |x: i32| x.wrapping_mul(2);
1203 apply::<RcFnBrand, VecBrand, _, _>(
1204 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1205 pure::<VecBrand, _>(x),
1206 ) == pure::<VecBrand, _>(f(x))
1207 }
1208
1209 #[quickcheck]
1211 fn applicative_composition(
1212 w: Vec<i32>,
1213 u_seeds: Vec<i32>,
1214 v_seeds: Vec<i32>,
1215 ) -> bool {
1216 let u_fns: Vec<_> = u_seeds
1217 .iter()
1218 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1219 .collect();
1220 let v_fns: Vec<_> = v_seeds
1221 .iter()
1222 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1223 .collect();
1224
1225 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1227 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1228
1229 let uv_fns: Vec<_> = u_fns
1233 .iter()
1234 .flat_map(|uf| {
1235 v_fns.iter().map(move |vf| {
1236 let uf = uf.clone();
1237 let vf = vf.clone();
1238 <RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1239 })
1240 })
1241 .collect();
1242
1243 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1244
1245 lhs == rhs
1246 }
1247
1248 #[quickcheck]
1250 fn applicative_interchange(y: i32) -> bool {
1251 let f = |x: i32| x.wrapping_mul(2);
1253 let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1254
1255 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1256
1257 let rhs_fn =
1258 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1259 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1260
1261 lhs == rhs
1262 }
1263
1264 #[quickcheck]
1268 fn semigroup_associativity(
1269 a: Vec<i32>,
1270 b: Vec<i32>,
1271 c: Vec<i32>,
1272 ) -> bool {
1273 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1274 }
1275
1276 #[quickcheck]
1280 fn monoid_left_identity(a: Vec<i32>) -> bool {
1281 append(empty::<Vec<i32>>(), a.clone()) == a
1282 }
1283
1284 #[quickcheck]
1286 fn monoid_right_identity(a: Vec<i32>) -> bool {
1287 append(a.clone(), empty::<Vec<i32>>()) == a
1288 }
1289
1290 #[quickcheck]
1294 fn monad_left_identity(a: i32) -> bool {
1295 let f = |x: i32| vec![x.wrapping_mul(2)];
1296 bind::<VecBrand, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1297 }
1298
1299 #[quickcheck]
1301 fn monad_right_identity(m: Vec<i32>) -> bool {
1302 bind::<VecBrand, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
1303 }
1304
1305 #[quickcheck]
1307 fn monad_associativity(m: Vec<i32>) -> bool {
1308 let f = |x: i32| vec![x.wrapping_mul(2)];
1309 let g = |x: i32| vec![x.wrapping_add(1)];
1310 bind::<VecBrand, _, _, _>(bind::<VecBrand, _, _, _>(m.clone(), f), g)
1311 == bind::<VecBrand, _, _, _>(m, |x| bind::<VecBrand, _, _, _>(f(x), g))
1312 }
1313
1314 #[test]
1318 fn map_empty() {
1319 assert_eq!(
1320 map::<VecBrand, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
1321 vec![] as Vec<i32>
1322 );
1323 }
1324
1325 #[test]
1327 fn bind_empty() {
1328 assert_eq!(
1329 bind::<VecBrand, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1330 vec![] as Vec<i32>
1331 );
1332 }
1333
1334 #[test]
1336 fn bind_returning_empty() {
1337 assert_eq!(
1338 bind::<VecBrand, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1339 vec![] as Vec<i32>
1340 );
1341 }
1342
1343 #[test]
1345 fn fold_right_empty() {
1346 assert_eq!(
1347 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _, _>(
1348 |x: i32, acc| x + acc,
1349 0,
1350 vec![]
1351 ),
1352 0
1353 );
1354 }
1355
1356 #[test]
1358 fn fold_left_empty() {
1359 assert_eq!(
1360 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _, _>(
1361 |acc, x: i32| acc + x,
1362 0,
1363 vec![]
1364 ),
1365 0
1366 );
1367 }
1368
1369 #[test]
1371 fn traverse_empty() {
1372 use crate::brands::OptionBrand;
1373 assert_eq!(
1374 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand, _>(
1375 |x: i32| Some(x + 1),
1376 vec![]
1377 ),
1378 Some(vec![])
1379 );
1380 }
1381
1382 #[test]
1384 fn traverse_returning_empty() {
1385 use crate::brands::OptionBrand;
1386 assert_eq!(
1387 crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand, _>(
1388 |_: i32| None::<i32>,
1389 vec![1, 2, 3]
1390 ),
1391 None
1392 );
1393 }
1394
1395 #[test]
1397 fn construct_empty_tail() {
1398 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1399 }
1400
1401 #[test]
1403 fn deconstruct_empty() {
1404 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1405 }
1406
1407 #[test]
1411 fn par_fold_map_empty() {
1412 let v: Vec<i32> = vec![];
1413 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1414 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1415 }
1416
1417 #[test]
1419 fn par_fold_map_single() {
1420 let v = vec![1];
1421 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1422 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1423 }
1424
1425 #[test]
1427 fn par_fold_map_multiple() {
1428 let v = vec![1, 2, 3];
1429 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1430 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1431 }
1432
1433 #[test]
1435 fn par_fold_right_multiple() {
1436 let v = vec![1, 2, 3];
1437 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1438 assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1439 }
1440
1441 #[quickcheck]
1445 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1446 filter_map::<VecBrand, _, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1447 }
1448
1449 #[quickcheck]
1451 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1452 filter_map::<VecBrand, _, _, _>(Some, x.clone()) == x
1453 }
1454
1455 #[quickcheck]
1457 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1458 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1459 let l = |i: i32| if i > 5 { Some(i) } else { None };
1460 let composed = |i| bind::<OptionBrand, _, _, _>(r(i), l);
1461
1462 filter_map::<VecBrand, _, _, _>(composed, x.clone())
1463 == filter_map::<VecBrand, _, _, _>(l, filter_map::<VecBrand, _, _, _>(r, x))
1464 }
1465
1466 #[quickcheck]
1468 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1469 let p = |i: i32| i % 2 == 0;
1470 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1471
1472 filter::<VecBrand, _, _>(p, x.clone()) == filter_map::<VecBrand, _, _, _>(maybe_bool, x)
1473 }
1474
1475 #[quickcheck]
1477 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1478 partition_map::<VecBrand, _, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1479 }
1480
1481 #[quickcheck]
1483 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1484 let (_, oks) = partition_map::<VecBrand, _, _, _, _>(Ok::<_, i32>, x.clone());
1485 oks == x
1486 }
1487
1488 #[quickcheck]
1490 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1491 let (errs, _) = partition_map::<VecBrand, _, _, _, _>(Err::<i32, _>, x.clone());
1492 errs == x
1493 }
1494
1495 #[quickcheck]
1497 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1498 let p = |i: i32| i % 2 == 0;
1499 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1500
1501 let (not_satisfied, satisfied) = partition::<VecBrand, _, _>(p, x.clone());
1502 let (errs, oks) = partition_map::<VecBrand, _, _, _, _>(either_bool, x);
1503
1504 satisfied == oks && not_satisfied == errs
1505 }
1506
1507 #[quickcheck]
1511 fn witherable_identity(x: Vec<i32>) -> bool {
1512 wither::<VecBrand, OptionBrand, _, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1513 }
1514
1515 #[quickcheck]
1517 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1518 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1519
1520 let lhs = wilt::<VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
1521 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1522 |res| separate::<VecBrand, _, _>(res),
1523 traverse::<VecBrand, _, _, OptionBrand, _>(p, x),
1524 );
1525
1526 lhs == rhs
1527 }
1528
1529 #[quickcheck]
1531 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1532 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1533
1534 let lhs = wither::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1535 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1536 |opt| compact::<VecBrand, _>(opt),
1537 traverse::<VecBrand, _, _, OptionBrand, _>(p, x),
1538 );
1539
1540 lhs == rhs
1541 }
1542
1543 #[test]
1547 fn compact_empty() {
1548 assert_eq!(compact::<VecBrand, _>(vec![] as Vec<Option<i32>>), vec![]);
1549 }
1550
1551 #[test]
1553 fn compact_with_none() {
1554 assert_eq!(compact::<VecBrand, _>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1555 }
1556
1557 #[test]
1559 fn separate_empty() {
1560 let (errs, oks) = separate::<VecBrand, _, _>(vec![] as Vec<Result<i32, i32>>);
1561 assert_eq!(oks, vec![]);
1562 assert_eq!(errs, vec![]);
1563 }
1564
1565 #[test]
1567 fn separate_mixed() {
1568 let (errs, oks) = separate::<VecBrand, _, _>(vec![Ok(1), Err(2), Ok(3)]);
1569 assert_eq!(oks, vec![1, 3]);
1570 assert_eq!(errs, vec![2]);
1571 }
1572
1573 #[test]
1575 fn partition_map_empty() {
1576 let (errs, oks) = partition_map::<VecBrand, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1577 assert_eq!(oks, vec![]);
1578 assert_eq!(errs, vec![]);
1579 }
1580
1581 #[test]
1583 fn partition_empty() {
1584 let (not_satisfied, satisfied) = partition::<VecBrand, _, _>(|x: i32| x > 0, vec![]);
1585 assert_eq!(satisfied, vec![]);
1586 assert_eq!(not_satisfied, vec![]);
1587 }
1588
1589 #[test]
1591 fn filter_map_empty() {
1592 assert_eq!(filter_map::<VecBrand, _, _, _>(|x: i32| Some(x), vec![]), vec![]);
1593 }
1594
1595 #[test]
1597 fn filter_empty() {
1598 assert_eq!(filter::<VecBrand, _, _>(|x: i32| x > 0, vec![]), vec![]);
1599 }
1600
1601 #[test]
1603 fn wilt_empty() {
1604 let res =
1605 wilt::<VecBrand, OptionBrand, _, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1606 assert_eq!(res, Some((vec![], vec![])));
1607 }
1608
1609 #[test]
1611 fn wither_empty() {
1612 let res = wither::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Some(x)), vec![]);
1613 assert_eq!(res, Some(vec![]));
1614 }
1615}