fp_library/types/vec.rs
1//! Implementations for [`Vec`].
2//!
3//! This module provides implementations of various type classes for the `Vec` type.
4
5#[cfg(feature = "rayon")]
6use rayon::prelude::*;
7
8use crate::{
9 Apply,
10 brands::{OptionBrand, VecBrand},
11 classes::{
12 applicative::Applicative, apply_first::ApplyFirst, apply_second::ApplySecond,
13 clonable_fn::ClonableFn, compactable::Compactable, filterable::Filterable,
14 foldable::Foldable, functor::Functor, lift::Lift, monoid::Monoid,
15 par_foldable::ParFoldable, pointed::Pointed, semiapplicative::Semiapplicative,
16 semigroup::Semigroup, semimonad::Semimonad, send_clonable_fn::SendClonableFn,
17 traversable::Traversable, witherable::Witherable,
18 },
19 impl_kind,
20 kinds::*,
21 types::Pair,
22};
23
24impl_kind! {
25 for VecBrand {
26 type Of<'a, A: 'a>: 'a = Vec<A>;
27 }
28}
29
30impl VecBrand {
31 /// Constructs a new vector by prepending a value to an existing vector.
32 ///
33 /// This method creates a new vector with the given head element followed by the elements of the tail vector.
34 ///
35 /// ### Type Signature
36 ///
37 /// `forall a. a -> Vec a -> Vec a`
38 ///
39 /// ### Type Parameters
40 ///
41 /// * `A`: The type of the elements in the vector.
42 ///
43 /// ### Parameters
44 ///
45 /// * `head`: A value to prepend to the vector.
46 /// * `tail`: A vector to prepend the value to.
47 ///
48 /// ### Returns
49 ///
50 /// A new vector consisting of the `head` element prepended to the `tail` vector.
51 ///
52 /// ### Examples
53 ///
54 /// ```
55 /// use fp_library::brands::VecBrand;
56 ///
57 /// let head = 1;
58 /// let tail = vec![2, 3];
59 /// let new_vec = VecBrand::construct(head, tail);
60 /// assert_eq!(new_vec, vec![1, 2, 3]);
61 ///
62 /// let empty_tail = vec![];
63 /// let single_element = VecBrand::construct(42, empty_tail);
64 /// assert_eq!(single_element, vec![42]);
65 /// ```
66 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 /// Deconstructs a slice into its head element and tail vector.
77 ///
78 /// This method splits a slice into its first element and the rest of the elements as a new vector.
79 ///
80 /// ### Type Signature
81 ///
82 /// `forall a. &[a] -> Option (a, Vec a)`
83 ///
84 /// ### Type Parameters
85 ///
86 /// * `A`: The type of the elements in the vector.
87 ///
88 /// ### Parameters
89 ///
90 /// * `slice`: The vector slice to deconstruct.
91 ///
92 /// ### Returns
93 ///
94 /// An [`Option`] containing a tuple of the head element and the remaining tail vector,
95 /// or [`None`] if the slice is empty.
96 ///
97 /// ### Examples
98 ///
99 /// ```
100 /// use fp_library::brands::VecBrand;
101 ///
102 /// let vec = vec![1, 2, 3];
103 /// let deconstructed = VecBrand::deconstruct(&vec);
104 /// assert_eq!(deconstructed, Some((1, vec![2, 3])));
105 ///
106 /// let empty: Vec<i32> = vec![];
107 /// assert_eq!(VecBrand::deconstruct(&empty), None);
108 /// ```
109 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
120impl Functor for VecBrand {
121 /// Maps a function over the vector.
122 ///
123 /// This method applies a function to each element of the vector, producing a new vector with the transformed values.
124 ///
125 /// ### Type Signature
126 ///
127 /// `forall b a. Functor Vec => (a -> b, Vec a) -> Vec b`
128 ///
129 /// ### Type Parameters
130 ///
131 /// * `B`: The type of the elements in the resulting vector.
132 /// * `A`: The type of the elements in the vector.
133 /// * `F`: The type of the function to apply.
134 ///
135 /// ### Parameters
136 ///
137 /// * `f`: The function to apply to each element.
138 /// * `fa`: The vector to map over.
139 ///
140 /// ### Returns
141 ///
142 /// A new vector containing the results of applying the function.
143 ///
144 /// ### Examples
145 ///
146 /// ```
147 /// use fp_library::functions::*;
148 /// use fp_library::brands::VecBrand;
149 ///
150 /// assert_eq!(map::<VecBrand, _, _, _>(|x: i32| x * 2, vec![1, 2, 3]), vec![2, 4, 6]);
151 /// ```
152 fn map<'a, B: 'a, A: 'a, F>(
153 f: F,
154 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
155 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
156 where
157 F: Fn(A) -> B + 'a,
158 {
159 fa.into_iter().map(f).collect()
160 }
161}
162
163impl Lift for VecBrand {
164 /// Lifts a binary function into the vector context (Cartesian product).
165 ///
166 /// This method applies a binary function to all pairs of elements from two vectors, producing a new vector containing the results (Cartesian product).
167 ///
168 /// ### Type Signature
169 ///
170 /// `forall c a b. Lift Vec => ((a, b) -> c, Vec a, Vec b) -> Vec c`
171 ///
172 /// ### Type Parameters
173 ///
174 /// * `C`: The type of the elements in the resulting vector.
175 /// * `A`: The type of the elements in the first vector.
176 /// * `B`: The type of the elements in the second vector.
177 /// * `F`: The type of the binary function.
178 ///
179 /// ### Parameters
180 ///
181 /// * `f`: The binary function to apply.
182 /// * `fa`: The first vector.
183 /// * `fb`: The second vector.
184 ///
185 /// ### Returns
186 ///
187 /// A new vector containing the results of applying the function to all pairs of elements.
188 ///
189 /// ### Examples
190 ///
191 /// ```
192 /// use fp_library::functions::*;
193 /// use fp_library::brands::VecBrand;
194 ///
195 /// assert_eq!(
196 /// lift2::<VecBrand, _, _, _, _>(|x, y| x + y, vec![1, 2], vec![10, 20]),
197 /// vec![11, 21, 12, 22]
198 /// );
199 /// ```
200 fn lift2<'a, C, A, B, F>(
201 f: F,
202 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
203 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
204 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
205 where
206 F: Fn(A, B) -> C + 'a,
207 A: Clone + 'a,
208 B: Clone + 'a,
209 C: 'a,
210 {
211 fa.iter().flat_map(|a| fb.iter().map(|b| f(a.clone(), b.clone()))).collect()
212 }
213}
214
215impl Pointed for VecBrand {
216 /// Wraps a value in a vector.
217 ///
218 /// This method creates a new vector containing the single given value.
219 ///
220 /// ### Type Signature
221 ///
222 /// `forall a. Pointed Vec => a -> Vec a`
223 ///
224 /// ### Type Parameters
225 ///
226 /// * `A`: The type of the value to wrap.
227 ///
228 /// ### Parameters
229 ///
230 /// * `a`: The value to wrap.
231 ///
232 /// ### Returns
233 ///
234 /// A vector containing the single value.
235 ///
236 /// ### Examples
237 ///
238 /// ```
239 /// use fp_library::functions::*;
240 /// use fp_library::brands::VecBrand;
241 ///
242 /// assert_eq!(pure::<VecBrand, _>(5), vec![5]);
243 /// ```
244 fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
245 vec![a]
246 }
247}
248
249impl ApplyFirst for VecBrand {}
250impl ApplySecond for VecBrand {}
251
252impl Semiapplicative for VecBrand {
253 /// Applies wrapped functions to wrapped values (Cartesian product).
254 ///
255 /// This method applies each function in the first vector to each value in the second vector, producing a new vector containing all the results.
256 ///
257 /// ### Type Signature
258 ///
259 /// `forall fn_brand b a. Semiapplicative Vec => (Vec (fn_brand a b), Vec a) -> Vec b`
260 ///
261 /// ### Type Parameters
262 ///
263 /// * `FnBrand`: The brand of the clonable function wrapper.
264 /// * `B`: The type of the output values.
265 /// * `A`: The type of the input values.
266 ///
267 /// ### Parameters
268 ///
269 /// * `ff`: The vector containing the functions.
270 /// * `fa`: The vector containing the values.
271 ///
272 /// ### Returns
273 ///
274 /// A new vector containing the results of applying each function to each value.
275 ///
276 /// ### Examples
277 ///
278 /// ```
279 /// use fp_library::{brands::*, classes::*, functions::*};
280 ///
281 /// let funcs = vec![
282 /// clonable_fn_new::<RcFnBrand, _, _>(|x: i32| x + 1),
283 /// clonable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2),
284 /// ];
285 /// assert_eq!(apply::<RcFnBrand, VecBrand, _, _>(funcs, vec![1, 2]), vec![2, 3, 2, 4]);
286 /// ```
287 fn apply<'a, FnBrand: 'a + ClonableFn, B: 'a, A: 'a + Clone>(
288 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as ClonableFn>::Of<'a, A, B>>),
289 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
290 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
291 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
292 }
293}
294
295impl Semimonad for VecBrand {
296 /// Chains vector computations (`flat_map`).
297 ///
298 /// This method applies a function that returns a vector to each element of the input vector, and then flattens the result.
299 ///
300 /// ### Type Signature
301 ///
302 /// `forall b a. Semimonad Vec => (Vec a, a -> Vec b) -> Vec b`
303 ///
304 /// ### Type Parameters
305 ///
306 /// * `B`: The type of the elements in the output vector.
307 /// * `A`: The type of the elements in the input vector.
308 /// * `F`: The type of the function to apply.
309 ///
310 /// ### Parameters
311 ///
312 /// * `ma`: The first vector.
313 /// * `f`: The function to apply to each element, returning a vector.
314 ///
315 /// ### Returns
316 ///
317 /// A new vector containing the flattened results.
318 ///
319 /// ### Examples
320 ///
321 /// ```
322 /// use fp_library::functions::*;
323 /// use fp_library::brands::VecBrand;
324 ///
325 /// assert_eq!(
326 /// bind::<VecBrand, _, _, _>(vec![1, 2], |x| vec![x, x * 2]),
327 /// vec![1, 2, 2, 4]
328 /// );
329 /// ```
330 fn bind<'a, B: 'a, A: 'a, F>(
331 ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
332 f: F,
333 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
334 where
335 F: Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
336 {
337 ma.into_iter().flat_map(f).collect()
338 }
339}
340
341impl Foldable for VecBrand {
342 /// Folds the vector from the right.
343 ///
344 /// This method performs a right-associative fold of the vector.
345 ///
346 /// ### Type Signature
347 ///
348 /// `forall b a. Foldable Vec => ((a, b) -> b, b, Vec a) -> b`
349 ///
350 /// ### Type Parameters
351 ///
352 /// * `FnBrand`: The brand of the clonable function to use.
353 /// * `B`: The type of the accumulator.
354 /// * `A`: The type of the elements in the vector.
355 /// * `Func`: The type of the folding function.
356 ///
357 /// ### Parameters
358 ///
359 /// * `func`: The folding function.
360 /// * `initial`: The initial value.
361 /// * `fa`: The vector to fold.
362 ///
363 /// ### Returns
364 ///
365 /// The final accumulator value.
366 ///
367 /// ### Examples
368 ///
369 /// ```
370 /// use fp_library::functions::*;
371 /// use fp_library::brands::{VecBrand, RcFnBrand};
372 ///
373 /// assert_eq!(fold_right::<RcFnBrand, VecBrand, _, _, _>(|x: i32, acc| x + acc, 0, vec![1, 2, 3]), 6);
374 /// ```
375 fn fold_right<'a, FnBrand, B: 'a, A: 'a, Func>(
376 func: Func,
377 initial: B,
378 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
379 ) -> B
380 where
381 Func: Fn(A, B) -> B + 'a,
382 FnBrand: ClonableFn + 'a,
383 {
384 fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
385 }
386
387 /// Folds the vector from the left.
388 ///
389 /// This method performs a left-associative fold of the vector.
390 ///
391 /// ### Type Signature
392 ///
393 /// `forall b a. Foldable Vec => ((b, a) -> b, b, Vec a) -> b`
394 ///
395 /// ### Type Parameters
396 ///
397 /// * `FnBrand`: The brand of the clonable function to use.
398 /// * `B`: The type of the accumulator.
399 /// * `A`: The type of the elements in the vector.
400 /// * `Func`: The type of the folding function.
401 ///
402 /// ### Parameters
403 ///
404 /// * `func`: The function to apply to the accumulator and each element.
405 /// * `initial`: The initial value of the accumulator.
406 /// * `fa`: The vector to fold.
407 ///
408 /// ### Returns
409 ///
410 /// The final accumulator value.
411 ///
412 /// ### Examples
413 ///
414 /// ```
415 /// use fp_library::functions::*;
416 /// use fp_library::brands::{VecBrand, RcFnBrand};
417 ///
418 /// assert_eq!(fold_left::<RcFnBrand, VecBrand, _, _, _>(|acc, x: i32| acc + x, 0, vec![1, 2, 3]), 6);
419 /// ```
420 fn fold_left<'a, FnBrand, B: 'a, A: 'a, Func>(
421 func: Func,
422 initial: B,
423 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
424 ) -> B
425 where
426 Func: Fn(B, A) -> B + 'a,
427 FnBrand: ClonableFn + 'a,
428 {
429 fa.into_iter().fold(initial, func)
430 }
431
432 /// Maps the values to a monoid and combines them.
433 ///
434 /// This method maps each element of the vector to a monoid and then combines the results using the monoid's `append` operation.
435 ///
436 /// ### Type Signature
437 ///
438 /// `forall m a. (Foldable Vec, Monoid m) => ((a) -> m, Vec a) -> m`
439 ///
440 /// ### Type Parameters
441 ///
442 /// * `FnBrand`: The brand of the clonable function to use.
443 /// * `M`: The type of the monoid.
444 /// * `A`: The type of the elements in the vector.
445 /// * `Func`: The type of the mapping function.
446 ///
447 /// ### Parameters
448 ///
449 /// * `func`: The mapping function.
450 /// * `fa`: The vector to fold.
451 ///
452 /// ### Returns
453 ///
454 /// The combined monoid value.
455 ///
456 /// ### Examples
457 ///
458 /// ```
459 /// use fp_library::functions::*;
460 /// use fp_library::brands::{VecBrand, RcFnBrand};
461 /// use fp_library::types::string; // Import to bring Monoid impl for String into scope
462 ///
463 /// assert_eq!(
464 /// fold_map::<RcFnBrand, VecBrand, _, _, _>(|x: i32| x.to_string(), vec![1, 2, 3]),
465 /// "123".to_string()
466 /// );
467 /// ```
468 fn fold_map<'a, FnBrand, M, A: 'a, Func>(
469 func: Func,
470 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
471 ) -> M
472 where
473 M: Monoid + 'a,
474 Func: Fn(A) -> M + 'a,
475 FnBrand: ClonableFn + 'a,
476 {
477 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
478 }
479}
480
481impl Traversable for VecBrand {
482 /// Traverses the vector with an applicative function.
483 ///
484 /// This method maps each element of the vector to a computation, evaluates them, and combines the results into an applicative context.
485 ///
486 /// ### Type Signature
487 ///
488 /// `forall f b a. (Traversable Vec, Applicative f) => (a -> f b, Vec a) -> f (Vec b)`
489 ///
490 /// ### Type Parameters
491 ///
492 /// * `F`: The applicative context.
493 /// * `B`: The type of the elements in the resulting traversable structure.
494 /// * `A`: The type of the elements in the traversable structure.
495 /// * `Func`: The type of the function to apply.
496 ///
497 /// ### Parameters
498 ///
499 /// * `func`: The function to apply to each element, returning a value in an applicative context.
500 /// * `ta`: The vector to traverse.
501 ///
502 /// ### Returns
503 ///
504 /// The vector wrapped in the applicative context.
505 ///
506 /// ### Examples
507 ///
508 /// ```
509 /// use fp_library::functions::*;
510 /// use fp_library::brands::{OptionBrand, VecBrand};
511 ///
512 /// assert_eq!(
513 /// traverse::<VecBrand, OptionBrand, _, _, _>(|x| Some(x * 2), vec![1, 2, 3]),
514 /// Some(vec![2, 4, 6])
515 /// );
516 /// ```
517 fn traverse<'a, F: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
518 func: Func,
519 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
520 ) -> 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>)>)
521 where
522 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
523 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
524 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
525 {
526 let len = ta.len();
527 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
528 F::lift2(
529 |mut v, b| {
530 v.push(b);
531 v
532 },
533 acc,
534 func(x),
535 )
536 })
537 }
538 /// Sequences a vector of applicative.
539 ///
540 /// This method evaluates the computations inside the vector and accumulates the results into an applicative context.
541 ///
542 /// ### Type Signature
543 ///
544 /// `forall f a. (Traversable Vec, Applicative f) => (Vec (f a)) -> f (Vec a)`
545 ///
546 /// ### Type Parameters
547 ///
548 /// * `F`: The applicative context.
549 /// * `A`: The type of the elements in the traversable structure.
550 ///
551 /// ### Parameters
552 ///
553 /// * `ta`: The vector containing the applicative values.
554 ///
555 /// ### Returns
556 ///
557 /// The vector wrapped in the applicative context.
558 ///
559 /// ### Examples
560 ///
561 /// ```
562 /// use fp_library::functions::*;
563 /// use fp_library::brands::{OptionBrand, VecBrand};
564 ///
565 /// assert_eq!(
566 /// sequence::<VecBrand, OptionBrand, _>(vec![Some(1), Some(2)]),
567 /// Some(vec![1, 2])
568 /// );
569 /// ```
570 fn sequence<'a, F: Applicative, A: 'a + Clone>(
571 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>)>)
572 ) -> 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>)>)
573 where
574 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
575 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
576 {
577 let len = ta.len();
578 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
579 F::lift2(
580 |mut v, a| {
581 v.push(a);
582 v
583 },
584 acc,
585 x,
586 )
587 })
588 }
589}
590
591impl<A: Clone> Semigroup for Vec<A> {
592 /// Appends one vector to another.
593 ///
594 /// This method concatenates two vectors.
595 ///
596 /// ### Type Signature
597 ///
598 /// `forall a. Semigroup (Vec a) => (Vec a, Vec a) -> Vec a`
599 ///
600 /// ### Type Parameters
601 ///
602 /// * `A`: The type of the elements in the vector.
603 ///
604 /// ### Parameters
605 ///
606 /// * `a`: The first vector.
607 /// * `b`: The second vector.
608 ///
609 /// ### Returns
610 ///
611 /// The concatenated vector.
612 ///
613 /// ### Examples
614 ///
615 /// ```
616 /// use fp_library::functions::*;
617 ///
618 /// assert_eq!(append(vec![1, 2], vec![3, 4]), vec![1, 2, 3, 4]);
619 /// ```
620 fn append(
621 a: Self,
622 b: Self,
623 ) -> Self {
624 [a, b].concat()
625 }
626}
627
628impl<A: Clone> Monoid for Vec<A> {
629 /// Returns an empty vector.
630 ///
631 /// This method returns a new, empty vector.
632 ///
633 /// ### Type Signature
634 ///
635 /// `forall a. Monoid (Vec a) => () -> Vec a`
636 ///
637 /// ### Type Parameters
638 ///
639 /// * `A`: The type of the elements in the vector.
640 ///
641 /// ### Returns
642 ///
643 /// An empty vector.
644 ///
645 /// ### Examples
646 ///
647 /// ```
648 /// use fp_library::functions::*;
649 ///
650 /// assert_eq!(empty::<Vec<i32>>(), vec![]);
651 /// ```
652 fn empty() -> Self {
653 Vec::new()
654 }
655}
656
657impl<FnBrand: SendClonableFn> ParFoldable<FnBrand> for VecBrand {
658 /// Maps values to a monoid and combines them in parallel.
659 ///
660 /// This method maps each element of the vector to a monoid and then combines the results using the monoid's `append` operation. The mapping and combination operations may be executed in parallel.
661 ///
662 /// **Note: The `rayon` feature must be enabled to use parallel iteration.**
663 ///
664 /// ### Type Signature
665 ///
666 /// `forall fn_brand m a. (ParFoldable Vec, Monoid m, Send m, Sync m) => (fn_brand a m, Vec a) -> m`
667 ///
668 /// ### Type Parameters
669 ///
670 /// * `FnBrand`: The brand of thread-safe function to use.
671 /// * `M`: The monoid type (must be `Send + Sync`).
672 /// * `A`: The element type (must be `Send + Sync`).
673 ///
674 /// ### Parameters
675 ///
676 /// * `func`: The thread-safe function to map each element to a monoid.
677 /// * `fa`: The vector to fold.
678 ///
679 /// ### Returns
680 ///
681 /// The combined monoid value.
682 ///
683 /// ### Examples
684 ///
685 /// ```
686 /// use fp_library::{brands::*, classes::*, functions::*, types::*};
687 ///
688 /// let v = vec![1, 2, 3];
689 /// let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
690 /// assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
691 /// ```
692 fn par_fold_map<'a, M, A>(
693 func: <FnBrand as SendClonableFn>::SendOf<'a, A, M>,
694 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
695 ) -> M
696 where
697 A: 'a + Clone + Send + Sync,
698 M: Monoid + Send + Sync + 'a,
699 {
700 #[cfg(feature = "rayon")]
701 {
702 fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
703 }
704 #[cfg(not(feature = "rayon"))]
705 {
706 #[allow(clippy::redundant_closure)]
707 fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
708 }
709 }
710}
711
712impl Compactable for VecBrand {
713 /// Compacts a vector of options.
714 ///
715 /// This method flattens a vector of options, discarding `None` values.
716 ///
717 /// ### Type Signature
718 ///
719 /// `forall a. Compactable Vec => Vec (Option a) -> Vec a`
720 ///
721 /// ### Type Parameters
722 ///
723 /// * `A`: The type of the elements.
724 ///
725 /// ### Parameters
726 ///
727 /// * `fa`: The vector of options.
728 ///
729 /// ### Returns
730 ///
731 /// The flattened vector.
732 ///
733 /// ### Examples
734 ///
735 /// ```
736 /// use fp_library::functions::*;
737 /// use fp_library::brands::VecBrand;
738 ///
739 /// let x = vec![Some(1), None, Some(2)];
740 /// let y = compact::<VecBrand, _>(x);
741 /// assert_eq!(y, vec![1, 2]);
742 /// ```
743 fn compact<'a, A: 'a>(
744 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
745 'a,
746 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
747 >)
748 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
749 fa.into_iter().flatten().collect()
750 }
751
752 /// Separates a vector of results.
753 ///
754 /// This method separates a vector of results into a pair of vectors.
755 ///
756 /// ### Type Signature
757 ///
758 /// `forall o e. Compactable Vec => Vec (Result o e) -> (Vec o, Vec e)`
759 ///
760 /// ### Type Parameters
761 ///
762 /// * `O`: The type of the success value.
763 /// * `E`: The type of the error value.
764 ///
765 /// ### Parameters
766 ///
767 /// * `fa`: The vector of results.
768 ///
769 /// ### Returns
770 ///
771 /// A pair of vectors.
772 ///
773 /// ### Examples
774 ///
775 /// ```
776 /// use fp_library::functions::*;
777 /// use fp_library::brands::VecBrand;
778 /// use fp_library::types::Pair;
779 ///
780 /// let x = vec![Ok(1), Err("error"), Ok(2)];
781 /// let Pair(oks, errs) = separate::<VecBrand, _, _>(x);
782 /// assert_eq!(oks, vec![1, 2]);
783 /// assert_eq!(errs, vec!["error"]);
784 /// ```
785 fn separate<'a, O: 'a, E: 'a>(
786 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
787 ) -> Pair<
788 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
789 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
790 > {
791 let mut oks = Vec::new();
792 let mut errs = Vec::new();
793 for result in fa {
794 match result {
795 Ok(o) => oks.push(o),
796 Err(e) => errs.push(e),
797 }
798 }
799 Pair(oks, errs)
800 }
801}
802
803impl Filterable for VecBrand {
804 /// Partitions a vector based on a function that returns a result.
805 ///
806 /// This method partitions a vector based on a function that returns a result.
807 ///
808 /// ### Type Signature
809 ///
810 /// `forall o e a. Filterable Vec => (a -> Result o e, Vec a) -> Pair (Vec o) (Vec e)`
811 ///
812 /// ### Type Parameters
813 ///
814 /// * `O`: The type of the success value.
815 /// * `E`: The type of the error value.
816 /// * `A`: The type of the input value.
817 /// * `Func`: The type of the function to apply.
818 ///
819 /// ### Parameters
820 ///
821 /// * `func`: The function to apply.
822 /// * `fa`: The vector to partition.
823 ///
824 /// ### Returns
825 ///
826 /// A pair of vectors.
827 ///
828 /// ### Examples
829 ///
830 /// ```
831 /// use fp_library::functions::*;
832 /// use fp_library::brands::VecBrand;
833 /// use fp_library::types::Pair;
834 ///
835 /// let x = vec![1, 2, 3, 4];
836 /// let Pair(oks, errs) = partition_map::<VecBrand, _, _, _, _>(|a| if a % 2 == 0 { Ok(a) } else { Err(a) }, x);
837 /// assert_eq!(oks, vec![2, 4]);
838 /// assert_eq!(errs, vec![1, 3]);
839 /// ```
840 fn partition_map<'a, O: 'a, E: 'a, A: 'a, Func>(
841 func: Func,
842 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
843 ) -> Pair<
844 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
845 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
846 >
847 where
848 Func: Fn(A) -> Result<O, E> + 'a,
849 {
850 let mut oks = Vec::new();
851 let mut errs = Vec::new();
852 for a in fa {
853 match func(a) {
854 Ok(o) => oks.push(o),
855 Err(e) => errs.push(e),
856 }
857 }
858 Pair(oks, errs)
859 }
860 /// Partitions a vector based on a predicate.
861 ///
862 /// This method partitions a vector based on a predicate.
863 ///
864 /// ### Type Signature
865 ///
866 /// `forall a. Filterable Vec => (a -> bool, Vec a) -> Pair (Vec a) (Vec a)`
867 ///
868 /// ### Type Parameters
869 ///
870 /// * `A`: The type of the elements.
871 /// * `Func`: The type of the predicate.
872 ///
873 /// ### Parameters
874 ///
875 /// * `func`: The predicate.
876 /// * `fa`: The vector to partition.
877 ///
878 /// ### Returns
879 ///
880 /// A pair of vectors.
881 ///
882 /// ### Examples
883 ///
884 /// ```
885 /// use fp_library::functions::*;
886 /// use fp_library::brands::VecBrand;
887 /// use fp_library::types::Pair;
888 ///
889 /// let x = vec![1, 2, 3, 4];
890 /// let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(|a| a % 2 == 0, x);
891 /// assert_eq!(satisfied, vec![2, 4]);
892 /// assert_eq!(not_satisfied, vec![1, 3]);
893 /// ```
894 fn partition<'a, A: 'a + Clone, Func>(
895 func: Func,
896 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
897 ) -> Pair<
898 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
899 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
900 >
901 where
902 Func: Fn(A) -> bool + 'a,
903 {
904 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
905 fa.into_iter().partition(|a| func(a.clone()));
906 Pair(satisfied, not_satisfied)
907 }
908
909 /// Maps a function over a vector and filters out `None` results.
910 ///
911 /// This method maps a function over a vector and filters out `None` results.
912 ///
913 /// ### Type Signature
914 ///
915 /// `forall b a. Filterable Vec => (a -> Option b, Vec a) -> Vec b`
916 ///
917 /// ### Type Parameters
918 ///
919 /// * `B`: The type of the result of applying the function.
920 /// * `A`: The type of the input value.
921 /// * `Func`: The type of the function to apply.
922 ///
923 /// ### Parameters
924 ///
925 /// * `func`: The function to apply.
926 /// * `fa`: The vector to filter and map.
927 ///
928 /// ### Returns
929 ///
930 /// The filtered and mapped vector.
931 ///
932 /// ### Examples
933 ///
934 /// ```
935 /// use fp_library::functions::*;
936 /// use fp_library::brands::VecBrand;
937 ///
938 /// let x = vec![1, 2, 3, 4];
939 /// let y = filter_map::<VecBrand, _, _, _>(|a| if a % 2 == 0 { Some(a * 2) } else { None }, x);
940 /// assert_eq!(y, vec![4, 8]);
941 /// ```
942 fn filter_map<'a, B: 'a, A: 'a, Func>(
943 func: Func,
944 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
945 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
946 where
947 Func: Fn(A) -> Option<B> + 'a,
948 {
949 fa.into_iter().filter_map(func).collect()
950 }
951
952 /// Filters a vector based on a predicate.
953 ///
954 /// This method filters a vector based on a predicate.
955 ///
956 /// ### Type Signature
957 ///
958 /// `forall a. Filterable Vec => (a -> bool, Vec a) -> Vec a`
959 ///
960 /// ### Type Parameters
961 ///
962 /// * `A`: The type of the elements.
963 /// * `Func`: The type of the predicate.
964 ///
965 /// ### Parameters
966 ///
967 /// * `func`: The predicate.
968 /// * `fa`: The vector to filter.
969 ///
970 /// ### Returns
971 ///
972 /// The filtered vector.
973 ///
974 /// ### Examples
975 ///
976 /// ```
977 /// use fp_library::functions::*;
978 /// use fp_library::brands::VecBrand;
979 ///
980 /// let x = vec![1, 2, 3, 4];
981 /// let y = filter::<VecBrand, _, _>(|a| a % 2 == 0, x);
982 /// assert_eq!(y, vec![2, 4]);
983 /// ```
984 fn filter<'a, A: 'a + Clone, Func>(
985 func: Func,
986 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
987 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
988 where
989 Func: Fn(A) -> bool + 'a,
990 {
991 fa.into_iter().filter(|a| func(a.clone())).collect()
992 }
993}
994
995impl Witherable for VecBrand {
996 /// Partitions a vector based on a function that returns a result in an applicative context.
997 ///
998 /// This method partitions a vector based on a function that returns a result in an applicative context.
999 ///
1000 /// ### Type Signature
1001 ///
1002 /// `forall m o e a. (Witherable Vec, Applicative m) => (a -> m (Result o e), Vec a) -> m (Pair (Vec o) (Vec e))`
1003 ///
1004 /// ### Type Parameters
1005 ///
1006 /// * `M`: The applicative context.
1007 /// * `O`: The type of the success value.
1008 /// * `E`: The type of the error value.
1009 /// * `A`: The type of the input value.
1010 /// * `Func`: The type of the function to apply.
1011 ///
1012 /// ### Parameters
1013 ///
1014 /// * `func`: The function to apply.
1015 /// * `ta`: The vector to partition.
1016 ///
1017 /// ### Returns
1018 ///
1019 /// The partitioned vector wrapped in the applicative context.
1020 ///
1021 /// ### Examples
1022 ///
1023 /// ```
1024 /// use fp_library::functions::*;
1025 /// use fp_library::brands::{VecBrand, OptionBrand};
1026 /// use fp_library::types::Pair;
1027 ///
1028 /// let x = vec![1, 2, 3, 4];
1029 /// let y = wilt::<VecBrand, OptionBrand, _, _, _, _>(|a| Some(if a % 2 == 0 { Ok(a) } else { Err(a) }), x);
1030 /// assert_eq!(y, Some(Pair(vec![2, 4], vec![1, 3])));
1031 /// ```
1032 fn wilt<'a, M: Applicative, O: 'a + Clone, E: 'a + Clone, A: 'a + Clone, Func>(
1033 func: Func,
1034 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1035 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1036 'a,
1037 Pair<
1038 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1039 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1040 >,
1041 >)
1042 where
1043 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
1044 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1045 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1046 {
1047 ta.into_iter().fold(M::pure(Pair(Vec::new(), Vec::new())), |acc, x| {
1048 M::lift2(
1049 |mut pair, res| {
1050 match res {
1051 Ok(o) => pair.0.push(o),
1052 Err(e) => pair.1.push(e),
1053 }
1054 pair
1055 },
1056 acc,
1057 func(x),
1058 )
1059 })
1060 }
1061
1062 /// Maps a function over a vector and filters out `None` results in an applicative context.
1063 ///
1064 /// This method maps a function over a vector and filters out `None` results in an applicative context.
1065 ///
1066 /// ### Type Signature
1067 ///
1068 /// `forall m b a. (Witherable Vec, Applicative m) => (a -> m (Option b), Vec a) -> m (Vec b)`
1069 ///
1070 /// ### Type Parameters
1071 ///
1072 /// * `M`: The applicative context.
1073 /// * `B`: The type of the result of applying the function.
1074 /// * `A`: The type of the elements in the input structure.
1075 /// * `Func`: The type of the function to apply.
1076 ///
1077 /// ### Parameters
1078 ///
1079 /// * `func`: The function to apply to each element, returning an `Option` in an applicative context.
1080 /// * `ta`: The vector to filter and map.
1081 ///
1082 /// ### Returns
1083 ///
1084 /// The filtered and mapped vector wrapped in the applicative context.
1085 ///
1086 /// ### Examples
1087 ///
1088 /// ```
1089 /// use fp_library::functions::*;
1090 /// use fp_library::brands::{VecBrand, OptionBrand};
1091 ///
1092 /// let x = vec![1, 2, 3, 4];
1093 /// let y = wither::<VecBrand, OptionBrand, _, _, _>(|a| Some(if a % 2 == 0 { Some(a * 2) } else { None }), x);
1094 /// assert_eq!(y, Some(vec![4, 8]));
1095 /// ```
1096 fn wither<'a, M: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
1097 func: Func,
1098 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1099 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1100 'a,
1101 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1102 >)
1103 where
1104 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1105 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1106 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1107 {
1108 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1109 M::lift2(
1110 |mut v, opt_b| {
1111 if let Some(b) = opt_b {
1112 v.push(b);
1113 }
1114 v
1115 },
1116 acc,
1117 func(x),
1118 )
1119 })
1120 }
1121}
1122
1123#[cfg(test)]
1124mod tests {
1125 use super::*;
1126 use crate::{brands::*, functions::*};
1127 use quickcheck_macros::quickcheck;
1128
1129 // Functor Laws
1130
1131 /// Tests the identity law for Functor.
1132 #[quickcheck]
1133 fn functor_identity(x: Vec<i32>) -> bool {
1134 map::<VecBrand, _, _, _>(identity, x.clone()) == x
1135 }
1136
1137 /// Tests the composition law for Functor.
1138 #[quickcheck]
1139 fn functor_composition(x: Vec<i32>) -> bool {
1140 let f = |x: i32| x.wrapping_add(1);
1141 let g = |x: i32| x.wrapping_mul(2);
1142 map::<VecBrand, _, _, _>(compose(f, g), x.clone())
1143 == map::<VecBrand, _, _, _>(f, map::<VecBrand, _, _, _>(g, x))
1144 }
1145
1146 // Applicative Laws
1147
1148 /// Tests the identity law for Applicative.
1149 #[quickcheck]
1150 fn applicative_identity(v: Vec<i32>) -> bool {
1151 apply::<RcFnBrand, VecBrand, _, _>(
1152 pure::<VecBrand, _>(<RcFnBrand as ClonableFn>::new(identity)),
1153 v.clone(),
1154 ) == v
1155 }
1156
1157 /// Tests the homomorphism law for Applicative.
1158 #[quickcheck]
1159 fn applicative_homomorphism(x: i32) -> bool {
1160 let f = |x: i32| x.wrapping_mul(2);
1161 apply::<RcFnBrand, VecBrand, _, _>(
1162 pure::<VecBrand, _>(<RcFnBrand as ClonableFn>::new(f)),
1163 pure::<VecBrand, _>(x),
1164 ) == pure::<VecBrand, _>(f(x))
1165 }
1166
1167 /// Tests the composition law for Applicative.
1168 #[quickcheck]
1169 fn applicative_composition(
1170 w: Vec<i32>,
1171 u_seeds: Vec<i32>,
1172 v_seeds: Vec<i32>,
1173 ) -> bool {
1174 let u_fns: Vec<_> = u_seeds
1175 .iter()
1176 .map(|&i| <RcFnBrand as ClonableFn>::new(move |x: i32| x.wrapping_add(i)))
1177 .collect();
1178 let v_fns: Vec<_> = v_seeds
1179 .iter()
1180 .map(|&i| <RcFnBrand as ClonableFn>::new(move |x: i32| x.wrapping_mul(i)))
1181 .collect();
1182
1183 // RHS: u <*> (v <*> w)
1184 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1185 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1186
1187 // LHS: pure(compose) <*> u <*> v <*> w
1188 // equivalent to (u . v) <*> w
1189 // We construct (u . v) manually as the cartesian product of compositions
1190 let uv_fns: Vec<_> = u_fns
1191 .iter()
1192 .flat_map(|uf| {
1193 v_fns.iter().map(move |vf| {
1194 let uf = uf.clone();
1195 let vf = vf.clone();
1196 <RcFnBrand as ClonableFn>::new(move |x| uf(vf(x)))
1197 })
1198 })
1199 .collect();
1200
1201 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1202
1203 lhs == rhs
1204 }
1205
1206 /// Tests the interchange law for Applicative.
1207 #[quickcheck]
1208 fn applicative_interchange(y: i32) -> bool {
1209 // u <*> pure y = pure ($ y) <*> u
1210 let f = |x: i32| x.wrapping_mul(2);
1211 let u = vec![<RcFnBrand as ClonableFn>::new(f)];
1212
1213 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1214
1215 let rhs_fn = <RcFnBrand as ClonableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1216 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1217
1218 lhs == rhs
1219 }
1220
1221 // Semigroup Laws
1222
1223 /// Tests the associativity law for Semigroup.
1224 #[quickcheck]
1225 fn semigroup_associativity(
1226 a: Vec<i32>,
1227 b: Vec<i32>,
1228 c: Vec<i32>,
1229 ) -> bool {
1230 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1231 }
1232
1233 // Monoid Laws
1234
1235 /// Tests the left identity law for Monoid.
1236 #[quickcheck]
1237 fn monoid_left_identity(a: Vec<i32>) -> bool {
1238 append(empty::<Vec<i32>>(), a.clone()) == a
1239 }
1240
1241 /// Tests the right identity law for Monoid.
1242 #[quickcheck]
1243 fn monoid_right_identity(a: Vec<i32>) -> bool {
1244 append(a.clone(), empty::<Vec<i32>>()) == a
1245 }
1246
1247 // Monad Laws
1248
1249 /// Tests the left identity law for Monad.
1250 #[quickcheck]
1251 fn monad_left_identity(a: i32) -> bool {
1252 let f = |x: i32| vec![x.wrapping_mul(2)];
1253 bind::<VecBrand, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1254 }
1255
1256 /// Tests the right identity law for Monad.
1257 #[quickcheck]
1258 fn monad_right_identity(m: Vec<i32>) -> bool {
1259 bind::<VecBrand, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
1260 }
1261
1262 /// Tests the associativity law for Monad.
1263 #[quickcheck]
1264 fn monad_associativity(m: Vec<i32>) -> bool {
1265 let f = |x: i32| vec![x.wrapping_mul(2)];
1266 let g = |x: i32| vec![x.wrapping_add(1)];
1267 bind::<VecBrand, _, _, _>(bind::<VecBrand, _, _, _>(m.clone(), f), g)
1268 == bind::<VecBrand, _, _, _>(m, |x| bind::<VecBrand, _, _, _>(f(x), g))
1269 }
1270
1271 // Edge Cases
1272
1273 /// Tests `map` on an empty vector.
1274 #[test]
1275 fn map_empty() {
1276 assert_eq!(
1277 map::<VecBrand, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
1278 vec![] as Vec<i32>
1279 );
1280 }
1281
1282 /// Tests `bind` on an empty vector.
1283 #[test]
1284 fn bind_empty() {
1285 assert_eq!(
1286 bind::<VecBrand, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1287 vec![] as Vec<i32>
1288 );
1289 }
1290
1291 /// Tests `bind` returning an empty vector.
1292 #[test]
1293 fn bind_returning_empty() {
1294 assert_eq!(
1295 bind::<VecBrand, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1296 vec![] as Vec<i32>
1297 );
1298 }
1299
1300 /// Tests `fold_right` on an empty vector.
1301 #[test]
1302 fn fold_right_empty() {
1303 assert_eq!(
1304 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _, _>(
1305 |x: i32, acc| x + acc,
1306 0,
1307 vec![]
1308 ),
1309 0
1310 );
1311 }
1312
1313 /// Tests `fold_left` on an empty vector.
1314 #[test]
1315 fn fold_left_empty() {
1316 assert_eq!(
1317 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _, _>(
1318 |acc, x: i32| acc + x,
1319 0,
1320 vec![]
1321 ),
1322 0
1323 );
1324 }
1325
1326 /// Tests `traverse` on an empty vector.
1327 #[test]
1328 fn traverse_empty() {
1329 use crate::brands::OptionBrand;
1330 assert_eq!(
1331 crate::classes::traversable::traverse::<VecBrand, OptionBrand, _, _, _>(
1332 |x: i32| Some(x + 1),
1333 vec![]
1334 ),
1335 Some(vec![])
1336 );
1337 }
1338
1339 /// Tests `traverse` returning an empty vector.
1340 #[test]
1341 fn traverse_returning_empty() {
1342 use crate::brands::OptionBrand;
1343 assert_eq!(
1344 crate::classes::traversable::traverse::<VecBrand, OptionBrand, _, _, _>(
1345 |_: i32| None::<i32>,
1346 vec![1, 2, 3]
1347 ),
1348 None
1349 );
1350 }
1351
1352 /// Tests `construct` with an empty tail.
1353 #[test]
1354 fn construct_empty_tail() {
1355 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1356 }
1357
1358 /// Tests `deconstruct` on an empty slice.
1359 #[test]
1360 fn deconstruct_empty() {
1361 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1362 }
1363
1364 // ParFoldable Tests
1365
1366 /// Tests `par_fold_map` on an empty vector.
1367 #[test]
1368 fn par_fold_map_empty() {
1369 let v: Vec<i32> = vec![];
1370 let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1371 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1372 }
1373
1374 /// Tests `par_fold_map` on a single element.
1375 #[test]
1376 fn par_fold_map_single() {
1377 let v = vec![1];
1378 let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1379 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1380 }
1381
1382 /// Tests `par_fold_map` on multiple elements.
1383 #[test]
1384 fn par_fold_map_multiple() {
1385 let v = vec![1, 2, 3];
1386 let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1387 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1388 }
1389
1390 /// Tests `par_fold_right` on multiple elements.
1391 #[test]
1392 fn par_fold_right_multiple() {
1393 let v = vec![1, 2, 3];
1394 let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1395 assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1396 }
1397
1398 // Filterable Laws
1399
1400 /// Tests `filterMap identity ≡ compact`.
1401 #[quickcheck]
1402 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1403 filter_map::<VecBrand, _, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1404 }
1405
1406 /// Tests `filterMap Just ≡ identity`.
1407 #[quickcheck]
1408 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1409 filter_map::<VecBrand, _, _, _>(Some, x.clone()) == x
1410 }
1411
1412 /// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
1413 #[quickcheck]
1414 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1415 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1416 let l = |i: i32| if i > 5 { Some(i) } else { None };
1417 let composed = |i| r(i).and_then(l);
1418
1419 filter_map::<VecBrand, _, _, _>(composed, x.clone())
1420 == filter_map::<VecBrand, _, _, _>(l, filter_map::<VecBrand, _, _, _>(r, x))
1421 }
1422
1423 /// Tests `filter ≡ filterMap <<< maybeBool`.
1424 #[quickcheck]
1425 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1426 let p = |i: i32| i % 2 == 0;
1427 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1428
1429 filter::<VecBrand, _, _>(p, x.clone()) == filter_map::<VecBrand, _, _, _>(maybe_bool, x)
1430 }
1431
1432 /// Tests `partitionMap identity ≡ separate`.
1433 #[quickcheck]
1434 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1435 partition_map::<VecBrand, _, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1436 }
1437
1438 /// Tests `partitionMap Right ≡ identity` (on the right side).
1439 #[quickcheck]
1440 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1441 let Pair(oks, _) = partition_map::<VecBrand, _, _, _, _>(Ok::<_, i32>, x.clone());
1442 oks == x
1443 }
1444
1445 /// Tests `partitionMap Left ≡ identity` (on the left side).
1446 #[quickcheck]
1447 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1448 let Pair(_, errs) = partition_map::<VecBrand, _, _, _, _>(Err::<i32, _>, x.clone());
1449 errs == x
1450 }
1451
1452 /// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
1453 #[quickcheck]
1454 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1455 let p = |i: i32| i % 2 == 0;
1456 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1457
1458 let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(p, x.clone());
1459 let Pair(oks, errs) = partition_map::<VecBrand, _, _, _, _>(either_bool, x);
1460
1461 satisfied == oks && not_satisfied == errs
1462 }
1463
1464 // Witherable Laws
1465
1466 /// Tests `wither (pure <<< Just) ≡ pure`.
1467 #[quickcheck]
1468 fn witherable_identity(x: Vec<i32>) -> bool {
1469 wither::<VecBrand, OptionBrand, _, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1470 }
1471
1472 /// Tests `wilt p ≡ map separate <<< traverse p`.
1473 #[quickcheck]
1474 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1475 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1476
1477 let lhs = wilt::<VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
1478 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1479 |res| separate::<VecBrand, _, _>(res),
1480 traverse::<VecBrand, OptionBrand, _, _, _>(p, x),
1481 );
1482
1483 lhs == rhs
1484 }
1485
1486 /// Tests `wither p ≡ map compact <<< traverse p`.
1487 #[quickcheck]
1488 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1489 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1490
1491 let lhs = wither::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1492 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1493 |opt| compact::<VecBrand, _>(opt),
1494 traverse::<VecBrand, OptionBrand, _, _, _>(p, x),
1495 );
1496
1497 lhs == rhs
1498 }
1499
1500 // Edge Cases
1501
1502 /// Tests `compact` on an empty vector.
1503 #[test]
1504 fn compact_empty() {
1505 assert_eq!(compact::<VecBrand, _>(vec![] as Vec<Option<i32>>), vec![]);
1506 }
1507
1508 /// Tests `compact` on a vector with `None`.
1509 #[test]
1510 fn compact_with_none() {
1511 assert_eq!(compact::<VecBrand, _>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1512 }
1513
1514 /// Tests `separate` on an empty vector.
1515 #[test]
1516 fn separate_empty() {
1517 let Pair(oks, errs) = separate::<VecBrand, _, _>(vec![] as Vec<Result<i32, i32>>);
1518 assert_eq!(oks, vec![]);
1519 assert_eq!(errs, vec![]);
1520 }
1521
1522 /// Tests `separate` on a vector with `Ok` and `Err`.
1523 #[test]
1524 fn separate_mixed() {
1525 let Pair(oks, errs) = separate::<VecBrand, _, _>(vec![Ok(1), Err(2), Ok(3)]);
1526 assert_eq!(oks, vec![1, 3]);
1527 assert_eq!(errs, vec![2]);
1528 }
1529
1530 /// Tests `partition_map` on an empty vector.
1531 #[test]
1532 fn partition_map_empty() {
1533 let Pair(oks, errs) =
1534 partition_map::<VecBrand, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1535 assert_eq!(oks, vec![]);
1536 assert_eq!(errs, vec![]);
1537 }
1538
1539 /// Tests `partition` on an empty vector.
1540 #[test]
1541 fn partition_empty() {
1542 let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(|x: i32| x > 0, vec![]);
1543 assert_eq!(satisfied, vec![]);
1544 assert_eq!(not_satisfied, vec![]);
1545 }
1546
1547 /// Tests `filter_map` on an empty vector.
1548 #[test]
1549 fn filter_map_empty() {
1550 assert_eq!(filter_map::<VecBrand, _, _, _>(|x: i32| Some(x), vec![]), vec![]);
1551 }
1552
1553 /// Tests `filter` on an empty vector.
1554 #[test]
1555 fn filter_empty() {
1556 assert_eq!(filter::<VecBrand, _, _>(|x: i32| x > 0, vec![]), vec![]);
1557 }
1558
1559 /// Tests `wilt` on an empty vector.
1560 #[test]
1561 fn wilt_empty() {
1562 let res =
1563 wilt::<VecBrand, OptionBrand, _, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1564 assert_eq!(res, Some(Pair(vec![], vec![])));
1565 }
1566
1567 /// Tests `wither` on an empty vector.
1568 #[test]
1569 fn wither_empty() {
1570 let res = wither::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Some(x)), vec![]);
1571 assert_eq!(res, Some(vec![]));
1572 }
1573}