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 cloneable_fn::CloneableFn, 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_cloneable_fn::SendCloneableFn,
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 cloneable 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 /// cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x + 1),
283 /// cloneable_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 + CloneableFn, B: 'a, A: 'a + Clone>(
288 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::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 cloneable 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: CloneableFn + '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 cloneable 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: CloneableFn + '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 cloneable 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::{brands::*, functions::*};
460 ///
461 /// assert_eq!(
462 /// fold_map::<RcFnBrand, VecBrand, _, _, _>(|x: i32| x.to_string(), vec![1, 2, 3]),
463 /// "123".to_string()
464 /// );
465 /// ```
466 fn fold_map<'a, FnBrand, M, A: 'a, Func>(
467 func: Func,
468 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
469 ) -> M
470 where
471 M: Monoid + 'a,
472 Func: Fn(A) -> M + 'a,
473 FnBrand: CloneableFn + 'a,
474 {
475 fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
476 }
477}
478
479impl Traversable for VecBrand {
480 /// Traverses the vector with an applicative function.
481 ///
482 /// This method maps each element of the vector to a computation, evaluates them, and combines the results into an applicative context.
483 ///
484 /// ### Type Signature
485 ///
486 /// `forall f b a. (Traversable Vec, Applicative f) => (a -> f b, Vec a) -> f (Vec b)`
487 ///
488 /// ### Type Parameters
489 ///
490 /// * `F`: The applicative context.
491 /// * `B`: The type of the elements in the resulting traversable structure.
492 /// * `A`: The type of the elements in the traversable structure.
493 /// * `Func`: The type of the function to apply.
494 ///
495 /// ### Parameters
496 ///
497 /// * `func`: The function to apply to each element, returning a value in an applicative context.
498 /// * `ta`: The vector to traverse.
499 ///
500 /// ### Returns
501 ///
502 /// The vector wrapped in the applicative context.
503 ///
504 /// ### Examples
505 ///
506 /// ```
507 /// use fp_library::functions::*;
508 /// use fp_library::brands::{OptionBrand, VecBrand};
509 ///
510 /// assert_eq!(
511 /// traverse::<VecBrand, OptionBrand, _, _, _>(|x| Some(x * 2), vec![1, 2, 3]),
512 /// Some(vec![2, 4, 6])
513 /// );
514 /// ```
515 fn traverse<'a, F: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
516 func: Func,
517 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
518 ) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
519 where
520 Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
521 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
522 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
523 {
524 let len = ta.len();
525 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
526 F::lift2(
527 |mut v, b| {
528 v.push(b);
529 v
530 },
531 acc,
532 func(x),
533 )
534 })
535 }
536 /// Sequences a vector of applicative.
537 ///
538 /// This method evaluates the computations inside the vector and accumulates the results into an applicative context.
539 ///
540 /// ### Type Signature
541 ///
542 /// `forall f a. (Traversable Vec, Applicative f) => (Vec (f a)) -> f (Vec a)`
543 ///
544 /// ### Type Parameters
545 ///
546 /// * `F`: The applicative context.
547 /// * `A`: The type of the elements in the traversable structure.
548 ///
549 /// ### Parameters
550 ///
551 /// * `ta`: The vector containing the applicative values.
552 ///
553 /// ### Returns
554 ///
555 /// The vector wrapped in the applicative context.
556 ///
557 /// ### Examples
558 ///
559 /// ```
560 /// use fp_library::functions::*;
561 /// use fp_library::brands::{OptionBrand, VecBrand};
562 ///
563 /// assert_eq!(
564 /// sequence::<VecBrand, OptionBrand, _>(vec![Some(1), Some(2)]),
565 /// Some(vec![1, 2])
566 /// );
567 /// ```
568 fn sequence<'a, F: Applicative, A: 'a + Clone>(
569 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>)>)
570 ) -> 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>)>)
571 where
572 Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
573 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
574 {
575 let len = ta.len();
576 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
577 F::lift2(
578 |mut v, a| {
579 v.push(a);
580 v
581 },
582 acc,
583 x,
584 )
585 })
586 }
587}
588
589impl<A: Clone> Semigroup for Vec<A> {
590 /// Appends one vector to another.
591 ///
592 /// This method concatenates two vectors.
593 ///
594 /// ### Type Signature
595 ///
596 /// `forall a. Semigroup (Vec a) => (Vec a, Vec a) -> Vec a`
597 ///
598 /// ### Type Parameters
599 ///
600 /// * `A`: The type of the elements in the vector.
601 ///
602 /// ### Parameters
603 ///
604 /// * `a`: The first vector.
605 /// * `b`: The second vector.
606 ///
607 /// ### Returns
608 ///
609 /// The concatenated vector.
610 ///
611 /// ### Examples
612 ///
613 /// ```
614 /// use fp_library::functions::*;
615 ///
616 /// assert_eq!(append(vec![1, 2], vec![3, 4]), vec![1, 2, 3, 4]);
617 /// ```
618 fn append(
619 a: Self,
620 b: Self,
621 ) -> Self {
622 [a, b].concat()
623 }
624}
625
626impl<A: Clone> Monoid for Vec<A> {
627 /// Returns an empty vector.
628 ///
629 /// This method returns a new, empty vector.
630 ///
631 /// ### Type Signature
632 ///
633 /// `forall a. Monoid (Vec a) => () -> Vec a`
634 ///
635 /// ### Type Parameters
636 ///
637 /// * `A`: The type of the elements in the vector.
638 ///
639 /// ### Returns
640 ///
641 /// An empty vector.
642 ///
643 /// ### Examples
644 ///
645 /// ```
646 /// use fp_library::functions::*;
647 ///
648 /// assert_eq!(empty::<Vec<i32>>(), vec![]);
649 /// ```
650 fn empty() -> Self {
651 Vec::new()
652 }
653}
654
655impl<FnBrand: SendCloneableFn> ParFoldable<FnBrand> for VecBrand {
656 /// Maps values to a monoid and combines them in parallel.
657 ///
658 /// 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.
659 ///
660 /// **Note: The `rayon` feature must be enabled to use parallel iteration.**
661 ///
662 /// ### Type Signature
663 ///
664 /// `forall fn_brand m a. (ParFoldable Vec, Monoid m, Send m, Sync m) => (fn_brand a m, Vec a) -> m`
665 ///
666 /// ### Type Parameters
667 ///
668 /// * `FnBrand`: The brand of thread-safe function to use.
669 /// * `M`: The monoid type (must be `Send + Sync`).
670 /// * `A`: The element type (must be `Send + Sync`).
671 ///
672 /// ### Parameters
673 ///
674 /// * `func`: The thread-safe function to map each element to a monoid.
675 /// * `fa`: The vector to fold.
676 ///
677 /// ### Returns
678 ///
679 /// The combined monoid value.
680 ///
681 /// ### Examples
682 ///
683 /// ```
684 /// use fp_library::{brands::*, functions::*};
685 ///
686 /// let v = vec![1, 2, 3];
687 /// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
688 /// assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
689 /// ```
690 fn par_fold_map<'a, M, A>(
691 func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
692 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
693 ) -> M
694 where
695 A: 'a + Clone + Send + Sync,
696 M: Monoid + Send + Sync + 'a,
697 {
698 #[cfg(feature = "rayon")]
699 {
700 fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
701 }
702 #[cfg(not(feature = "rayon"))]
703 {
704 #[allow(clippy::redundant_closure)]
705 fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
706 }
707 }
708}
709
710impl Compactable for VecBrand {
711 /// Compacts a vector of options.
712 ///
713 /// This method flattens a vector of options, discarding `None` values.
714 ///
715 /// ### Type Signature
716 ///
717 /// `forall a. Compactable Vec => Vec (Option a) -> Vec a`
718 ///
719 /// ### Type Parameters
720 ///
721 /// * `A`: The type of the elements.
722 ///
723 /// ### Parameters
724 ///
725 /// * `fa`: The vector of options.
726 ///
727 /// ### Returns
728 ///
729 /// The flattened vector.
730 ///
731 /// ### Examples
732 ///
733 /// ```
734 /// use fp_library::functions::*;
735 /// use fp_library::brands::VecBrand;
736 ///
737 /// let x = vec![Some(1), None, Some(2)];
738 /// let y = compact::<VecBrand, _>(x);
739 /// assert_eq!(y, vec![1, 2]);
740 /// ```
741 fn compact<'a, A: 'a>(
742 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
743 'a,
744 Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
745 >)
746 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
747 fa.into_iter().flatten().collect()
748 }
749
750 /// Separates a vector of results.
751 ///
752 /// This method separates a vector of results into a pair of vectors.
753 ///
754 /// ### Type Signature
755 ///
756 /// `forall o e. Compactable Vec => Vec (Result o e) -> (Vec o, Vec e)`
757 ///
758 /// ### Type Parameters
759 ///
760 /// * `O`: The type of the success value.
761 /// * `E`: The type of the error value.
762 ///
763 /// ### Parameters
764 ///
765 /// * `fa`: The vector of results.
766 ///
767 /// ### Returns
768 ///
769 /// A pair of vectors.
770 ///
771 /// ### Examples
772 ///
773 /// ```
774 /// use fp_library::{brands::*, functions::*, types::*};
775 ///
776 /// let x = vec![Ok(1), Err("error"), Ok(2)];
777 /// let Pair(oks, errs) = separate::<VecBrand, _, _>(x);
778 /// assert_eq!(oks, vec![1, 2]);
779 /// assert_eq!(errs, vec!["error"]);
780 /// ```
781 fn separate<'a, O: 'a, E: 'a>(
782 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
783 ) -> Pair<
784 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
785 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
786 > {
787 let mut oks = Vec::new();
788 let mut errs = Vec::new();
789 for result in fa {
790 match result {
791 Ok(o) => oks.push(o),
792 Err(e) => errs.push(e),
793 }
794 }
795 Pair(oks, errs)
796 }
797}
798
799impl Filterable for VecBrand {
800 /// Partitions a vector based on a function that returns a result.
801 ///
802 /// This method partitions a vector based on a function that returns a result.
803 ///
804 /// ### Type Signature
805 ///
806 /// `forall o e a. Filterable Vec => (a -> Result o e, Vec a) -> Pair (Vec o) (Vec e)`
807 ///
808 /// ### Type Parameters
809 ///
810 /// * `O`: The type of the success value.
811 /// * `E`: The type of the error value.
812 /// * `A`: The type of the input value.
813 /// * `Func`: The type of the function to apply.
814 ///
815 /// ### Parameters
816 ///
817 /// * `func`: The function to apply.
818 /// * `fa`: The vector to partition.
819 ///
820 /// ### Returns
821 ///
822 /// A pair of vectors.
823 ///
824 /// ### Examples
825 ///
826 /// ```
827 /// use fp_library::{brands::*, functions::*, types::*};
828 ///
829 /// let x = vec![1, 2, 3, 4];
830 /// let Pair(oks, errs) = partition_map::<VecBrand, _, _, _, _>(|a| if a % 2 == 0 { Ok(a) } else { Err(a) }, x);
831 /// assert_eq!(oks, vec![2, 4]);
832 /// assert_eq!(errs, vec![1, 3]);
833 /// ```
834 fn partition_map<'a, O: 'a, E: 'a, A: 'a, Func>(
835 func: Func,
836 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
837 ) -> Pair<
838 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
839 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
840 >
841 where
842 Func: Fn(A) -> Result<O, E> + 'a,
843 {
844 let mut oks = Vec::new();
845 let mut errs = Vec::new();
846 for a in fa {
847 match func(a) {
848 Ok(o) => oks.push(o),
849 Err(e) => errs.push(e),
850 }
851 }
852 Pair(oks, errs)
853 }
854 /// Partitions a vector based on a predicate.
855 ///
856 /// This method partitions a vector based on a predicate.
857 ///
858 /// ### Type Signature
859 ///
860 /// `forall a. Filterable Vec => (a -> bool, Vec a) -> Pair (Vec a) (Vec a)`
861 ///
862 /// ### Type Parameters
863 ///
864 /// * `A`: The type of the elements.
865 /// * `Func`: The type of the predicate.
866 ///
867 /// ### Parameters
868 ///
869 /// * `func`: The predicate.
870 /// * `fa`: The vector to partition.
871 ///
872 /// ### Returns
873 ///
874 /// A pair of vectors.
875 ///
876 /// ### Examples
877 ///
878 /// ```
879 /// use fp_library::{brands::*, functions::*, types::*};
880 ///
881 /// let x = vec![1, 2, 3, 4];
882 /// let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(|a| a % 2 == 0, x);
883 /// assert_eq!(satisfied, vec![2, 4]);
884 /// assert_eq!(not_satisfied, vec![1, 3]);
885 /// ```
886 fn partition<'a, A: 'a + Clone, Func>(
887 func: Func,
888 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
889 ) -> Pair<
890 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
891 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
892 >
893 where
894 Func: Fn(A) -> bool + 'a,
895 {
896 let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
897 fa.into_iter().partition(|a| func(a.clone()));
898 Pair(satisfied, not_satisfied)
899 }
900
901 /// Maps a function over a vector and filters out `None` results.
902 ///
903 /// This method maps a function over a vector and filters out `None` results.
904 ///
905 /// ### Type Signature
906 ///
907 /// `forall b a. Filterable Vec => (a -> Option b, Vec a) -> Vec b`
908 ///
909 /// ### Type Parameters
910 ///
911 /// * `B`: The type of the result of applying the function.
912 /// * `A`: The type of the input value.
913 /// * `Func`: The type of the function to apply.
914 ///
915 /// ### Parameters
916 ///
917 /// * `func`: The function to apply.
918 /// * `fa`: The vector to filter and map.
919 ///
920 /// ### Returns
921 ///
922 /// The filtered and mapped vector.
923 ///
924 /// ### Examples
925 ///
926 /// ```
927 /// use fp_library::functions::*;
928 /// use fp_library::brands::VecBrand;
929 ///
930 /// let x = vec![1, 2, 3, 4];
931 /// let y = filter_map::<VecBrand, _, _, _>(|a| if a % 2 == 0 { Some(a * 2) } else { None }, x);
932 /// assert_eq!(y, vec![4, 8]);
933 /// ```
934 fn filter_map<'a, B: 'a, A: 'a, Func>(
935 func: Func,
936 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
937 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
938 where
939 Func: Fn(A) -> Option<B> + 'a,
940 {
941 fa.into_iter().filter_map(func).collect()
942 }
943
944 /// Filters a vector based on a predicate.
945 ///
946 /// This method filters a vector based on a predicate.
947 ///
948 /// ### Type Signature
949 ///
950 /// `forall a. Filterable Vec => (a -> bool, Vec a) -> Vec a`
951 ///
952 /// ### Type Parameters
953 ///
954 /// * `A`: The type of the elements.
955 /// * `Func`: The type of the predicate.
956 ///
957 /// ### Parameters
958 ///
959 /// * `func`: The predicate.
960 /// * `fa`: The vector to filter.
961 ///
962 /// ### Returns
963 ///
964 /// The filtered vector.
965 ///
966 /// ### Examples
967 ///
968 /// ```
969 /// use fp_library::functions::*;
970 /// use fp_library::brands::VecBrand;
971 ///
972 /// let x = vec![1, 2, 3, 4];
973 /// let y = filter::<VecBrand, _, _>(|a| a % 2 == 0, x);
974 /// assert_eq!(y, vec![2, 4]);
975 /// ```
976 fn filter<'a, A: 'a + Clone, Func>(
977 func: Func,
978 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
979 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
980 where
981 Func: Fn(A) -> bool + 'a,
982 {
983 fa.into_iter().filter(|a| func(a.clone())).collect()
984 }
985}
986
987impl Witherable for VecBrand {
988 /// Partitions a vector based on a function that returns a result in an applicative context.
989 ///
990 /// This method partitions a vector based on a function that returns a result in an applicative context.
991 ///
992 /// ### Type Signature
993 ///
994 /// `forall m o e a. (Witherable Vec, Applicative m) => (a -> m (Result o e), Vec a) -> m (Pair (Vec o) (Vec e))`
995 ///
996 /// ### Type Parameters
997 ///
998 /// * `M`: The applicative context.
999 /// * `O`: The type of the success value.
1000 /// * `E`: The type of the error value.
1001 /// * `A`: The type of the input value.
1002 /// * `Func`: The type of the function to apply.
1003 ///
1004 /// ### Parameters
1005 ///
1006 /// * `func`: The function to apply.
1007 /// * `ta`: The vector to partition.
1008 ///
1009 /// ### Returns
1010 ///
1011 /// The partitioned vector wrapped in the applicative context.
1012 ///
1013 /// ### Examples
1014 ///
1015 /// ```
1016 /// use fp_library::{brands::*, functions::*, types::*};
1017 ///
1018 /// let x = vec![1, 2, 3, 4];
1019 /// let y = wilt::<VecBrand, OptionBrand, _, _, _, _>(|a| Some(if a % 2 == 0 { Ok(a) } else { Err(a) }), x);
1020 /// assert_eq!(y, Some(Pair(vec![2, 4], vec![1, 3])));
1021 /// ```
1022 fn wilt<'a, M: Applicative, O: 'a + Clone, E: 'a + Clone, A: 'a + Clone, Func>(
1023 func: Func,
1024 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1025 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1026 'a,
1027 Pair<
1028 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1029 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1030 >,
1031 >)
1032 where
1033 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
1034 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1035 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1036 {
1037 ta.into_iter().fold(M::pure(Pair(Vec::new(), Vec::new())), |acc, x| {
1038 M::lift2(
1039 |mut pair, res| {
1040 match res {
1041 Ok(o) => pair.0.push(o),
1042 Err(e) => pair.1.push(e),
1043 }
1044 pair
1045 },
1046 acc,
1047 func(x),
1048 )
1049 })
1050 }
1051
1052 /// Maps a function over a vector and filters out `None` results in an applicative context.
1053 ///
1054 /// This method maps a function over a vector and filters out `None` results in an applicative context.
1055 ///
1056 /// ### Type Signature
1057 ///
1058 /// `forall m b a. (Witherable Vec, Applicative m) => (a -> m (Option b), Vec a) -> m (Vec b)`
1059 ///
1060 /// ### Type Parameters
1061 ///
1062 /// * `M`: The applicative context.
1063 /// * `B`: The type of the result of applying the function.
1064 /// * `A`: The type of the elements in the input structure.
1065 /// * `Func`: The type of the function to apply.
1066 ///
1067 /// ### Parameters
1068 ///
1069 /// * `func`: The function to apply to each element, returning an `Option` in an applicative context.
1070 /// * `ta`: The vector to filter and map.
1071 ///
1072 /// ### Returns
1073 ///
1074 /// The filtered and mapped vector wrapped in the applicative context.
1075 ///
1076 /// ### Examples
1077 ///
1078 /// ```
1079 /// use fp_library::functions::*;
1080 /// use fp_library::brands::{VecBrand, OptionBrand};
1081 ///
1082 /// let x = vec![1, 2, 3, 4];
1083 /// let y = wither::<VecBrand, OptionBrand, _, _, _>(|a| Some(if a % 2 == 0 { Some(a * 2) } else { None }), x);
1084 /// assert_eq!(y, Some(vec![4, 8]));
1085 /// ```
1086 fn wither<'a, M: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
1087 func: Func,
1088 ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1089 ) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1090 'a,
1091 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1092 >)
1093 where
1094 Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1095 Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1096 Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1097 {
1098 ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1099 M::lift2(
1100 |mut v, opt_b| {
1101 if let Some(b) = opt_b {
1102 v.push(b);
1103 }
1104 v
1105 },
1106 acc,
1107 func(x),
1108 )
1109 })
1110 }
1111}
1112
1113#[cfg(test)]
1114mod tests {
1115 use super::*;
1116 use crate::{brands::*, functions::*};
1117 use quickcheck_macros::quickcheck;
1118
1119 // Functor Laws
1120
1121 /// Tests the identity law for Functor.
1122 #[quickcheck]
1123 fn functor_identity(x: Vec<i32>) -> bool {
1124 map::<VecBrand, _, _, _>(identity, x.clone()) == x
1125 }
1126
1127 /// Tests the composition law for Functor.
1128 #[quickcheck]
1129 fn functor_composition(x: Vec<i32>) -> bool {
1130 let f = |x: i32| x.wrapping_add(1);
1131 let g = |x: i32| x.wrapping_mul(2);
1132 map::<VecBrand, _, _, _>(compose(f, g), x.clone())
1133 == map::<VecBrand, _, _, _>(f, map::<VecBrand, _, _, _>(g, x))
1134 }
1135
1136 // Applicative Laws
1137
1138 /// Tests the identity law for Applicative.
1139 #[quickcheck]
1140 fn applicative_identity(v: Vec<i32>) -> bool {
1141 apply::<RcFnBrand, VecBrand, _, _>(
1142 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1143 v.clone(),
1144 ) == v
1145 }
1146
1147 /// Tests the homomorphism law for Applicative.
1148 #[quickcheck]
1149 fn applicative_homomorphism(x: i32) -> bool {
1150 let f = |x: i32| x.wrapping_mul(2);
1151 apply::<RcFnBrand, VecBrand, _, _>(
1152 pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1153 pure::<VecBrand, _>(x),
1154 ) == pure::<VecBrand, _>(f(x))
1155 }
1156
1157 /// Tests the composition law for Applicative.
1158 #[quickcheck]
1159 fn applicative_composition(
1160 w: Vec<i32>,
1161 u_seeds: Vec<i32>,
1162 v_seeds: Vec<i32>,
1163 ) -> bool {
1164 let u_fns: Vec<_> = u_seeds
1165 .iter()
1166 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1167 .collect();
1168 let v_fns: Vec<_> = v_seeds
1169 .iter()
1170 .map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1171 .collect();
1172
1173 // RHS: u <*> (v <*> w)
1174 let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1175 let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1176
1177 // LHS: pure(compose) <*> u <*> v <*> w
1178 // equivalent to (u . v) <*> w
1179 // We construct (u . v) manually as the cartesian product of compositions
1180 let uv_fns: Vec<_> = u_fns
1181 .iter()
1182 .flat_map(|uf| {
1183 v_fns.iter().map(move |vf| {
1184 let uf = uf.clone();
1185 let vf = vf.clone();
1186 <RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1187 })
1188 })
1189 .collect();
1190
1191 let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1192
1193 lhs == rhs
1194 }
1195
1196 /// Tests the interchange law for Applicative.
1197 #[quickcheck]
1198 fn applicative_interchange(y: i32) -> bool {
1199 // u <*> pure y = pure ($ y) <*> u
1200 let f = |x: i32| x.wrapping_mul(2);
1201 let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1202
1203 let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1204
1205 let rhs_fn =
1206 <RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1207 let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1208
1209 lhs == rhs
1210 }
1211
1212 // Semigroup Laws
1213
1214 /// Tests the associativity law for Semigroup.
1215 #[quickcheck]
1216 fn semigroup_associativity(
1217 a: Vec<i32>,
1218 b: Vec<i32>,
1219 c: Vec<i32>,
1220 ) -> bool {
1221 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1222 }
1223
1224 // Monoid Laws
1225
1226 /// Tests the left identity law for Monoid.
1227 #[quickcheck]
1228 fn monoid_left_identity(a: Vec<i32>) -> bool {
1229 append(empty::<Vec<i32>>(), a.clone()) == a
1230 }
1231
1232 /// Tests the right identity law for Monoid.
1233 #[quickcheck]
1234 fn monoid_right_identity(a: Vec<i32>) -> bool {
1235 append(a.clone(), empty::<Vec<i32>>()) == a
1236 }
1237
1238 // Monad Laws
1239
1240 /// Tests the left identity law for Monad.
1241 #[quickcheck]
1242 fn monad_left_identity(a: i32) -> bool {
1243 let f = |x: i32| vec![x.wrapping_mul(2)];
1244 bind::<VecBrand, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1245 }
1246
1247 /// Tests the right identity law for Monad.
1248 #[quickcheck]
1249 fn monad_right_identity(m: Vec<i32>) -> bool {
1250 bind::<VecBrand, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
1251 }
1252
1253 /// Tests the associativity law for Monad.
1254 #[quickcheck]
1255 fn monad_associativity(m: Vec<i32>) -> bool {
1256 let f = |x: i32| vec![x.wrapping_mul(2)];
1257 let g = |x: i32| vec![x.wrapping_add(1)];
1258 bind::<VecBrand, _, _, _>(bind::<VecBrand, _, _, _>(m.clone(), f), g)
1259 == bind::<VecBrand, _, _, _>(m, |x| bind::<VecBrand, _, _, _>(f(x), g))
1260 }
1261
1262 // Edge Cases
1263
1264 /// Tests `map` on an empty vector.
1265 #[test]
1266 fn map_empty() {
1267 assert_eq!(
1268 map::<VecBrand, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
1269 vec![] as Vec<i32>
1270 );
1271 }
1272
1273 /// Tests `bind` on an empty vector.
1274 #[test]
1275 fn bind_empty() {
1276 assert_eq!(
1277 bind::<VecBrand, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1278 vec![] as Vec<i32>
1279 );
1280 }
1281
1282 /// Tests `bind` returning an empty vector.
1283 #[test]
1284 fn bind_returning_empty() {
1285 assert_eq!(
1286 bind::<VecBrand, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1287 vec![] as Vec<i32>
1288 );
1289 }
1290
1291 /// Tests `fold_right` on an empty vector.
1292 #[test]
1293 fn fold_right_empty() {
1294 assert_eq!(
1295 crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _, _>(
1296 |x: i32, acc| x + acc,
1297 0,
1298 vec![]
1299 ),
1300 0
1301 );
1302 }
1303
1304 /// Tests `fold_left` on an empty vector.
1305 #[test]
1306 fn fold_left_empty() {
1307 assert_eq!(
1308 crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _, _>(
1309 |acc, x: i32| acc + x,
1310 0,
1311 vec![]
1312 ),
1313 0
1314 );
1315 }
1316
1317 /// Tests `traverse` on an empty vector.
1318 #[test]
1319 fn traverse_empty() {
1320 use crate::brands::OptionBrand;
1321 assert_eq!(
1322 crate::classes::traversable::traverse::<VecBrand, OptionBrand, _, _, _>(
1323 |x: i32| Some(x + 1),
1324 vec![]
1325 ),
1326 Some(vec![])
1327 );
1328 }
1329
1330 /// Tests `traverse` returning an empty vector.
1331 #[test]
1332 fn traverse_returning_empty() {
1333 use crate::brands::OptionBrand;
1334 assert_eq!(
1335 crate::classes::traversable::traverse::<VecBrand, OptionBrand, _, _, _>(
1336 |_: i32| None::<i32>,
1337 vec![1, 2, 3]
1338 ),
1339 None
1340 );
1341 }
1342
1343 /// Tests `construct` with an empty tail.
1344 #[test]
1345 fn construct_empty_tail() {
1346 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1347 }
1348
1349 /// Tests `deconstruct` on an empty slice.
1350 #[test]
1351 fn deconstruct_empty() {
1352 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1353 }
1354
1355 // ParFoldable Tests
1356
1357 /// Tests `par_fold_map` on an empty vector.
1358 #[test]
1359 fn par_fold_map_empty() {
1360 let v: Vec<i32> = vec![];
1361 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1362 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1363 }
1364
1365 /// Tests `par_fold_map` on a single element.
1366 #[test]
1367 fn par_fold_map_single() {
1368 let v = vec![1];
1369 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1370 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1371 }
1372
1373 /// Tests `par_fold_map` on multiple elements.
1374 #[test]
1375 fn par_fold_map_multiple() {
1376 let v = vec![1, 2, 3];
1377 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1378 assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1379 }
1380
1381 /// Tests `par_fold_right` on multiple elements.
1382 #[test]
1383 fn par_fold_right_multiple() {
1384 let v = vec![1, 2, 3];
1385 let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1386 assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1387 }
1388
1389 // Filterable Laws
1390
1391 /// Tests `filterMap identity ≡ compact`.
1392 #[quickcheck]
1393 fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1394 filter_map::<VecBrand, _, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1395 }
1396
1397 /// Tests `filterMap Just ≡ identity`.
1398 #[quickcheck]
1399 fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1400 filter_map::<VecBrand, _, _, _>(Some, x.clone()) == x
1401 }
1402
1403 /// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
1404 #[quickcheck]
1405 fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1406 let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1407 let l = |i: i32| if i > 5 { Some(i) } else { None };
1408 let composed = |i| r(i).and_then(l);
1409
1410 filter_map::<VecBrand, _, _, _>(composed, x.clone())
1411 == filter_map::<VecBrand, _, _, _>(l, filter_map::<VecBrand, _, _, _>(r, x))
1412 }
1413
1414 /// Tests `filter ≡ filterMap <<< maybeBool`.
1415 #[quickcheck]
1416 fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1417 let p = |i: i32| i % 2 == 0;
1418 let maybe_bool = |i| if p(i) { Some(i) } else { None };
1419
1420 filter::<VecBrand, _, _>(p, x.clone()) == filter_map::<VecBrand, _, _, _>(maybe_bool, x)
1421 }
1422
1423 /// Tests `partitionMap identity ≡ separate`.
1424 #[quickcheck]
1425 fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1426 partition_map::<VecBrand, _, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1427 }
1428
1429 /// Tests `partitionMap Right ≡ identity` (on the right side).
1430 #[quickcheck]
1431 fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1432 let Pair(oks, _) = partition_map::<VecBrand, _, _, _, _>(Ok::<_, i32>, x.clone());
1433 oks == x
1434 }
1435
1436 /// Tests `partitionMap Left ≡ identity` (on the left side).
1437 #[quickcheck]
1438 fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1439 let Pair(_, errs) = partition_map::<VecBrand, _, _, _, _>(Err::<i32, _>, x.clone());
1440 errs == x
1441 }
1442
1443 /// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
1444 #[quickcheck]
1445 fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1446 let p = |i: i32| i % 2 == 0;
1447 let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1448
1449 let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(p, x.clone());
1450 let Pair(oks, errs) = partition_map::<VecBrand, _, _, _, _>(either_bool, x);
1451
1452 satisfied == oks && not_satisfied == errs
1453 }
1454
1455 // Witherable Laws
1456
1457 /// Tests `wither (pure <<< Just) ≡ pure`.
1458 #[quickcheck]
1459 fn witherable_identity(x: Vec<i32>) -> bool {
1460 wither::<VecBrand, OptionBrand, _, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1461 }
1462
1463 /// Tests `wilt p ≡ map separate <<< traverse p`.
1464 #[quickcheck]
1465 fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1466 let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1467
1468 let lhs = wilt::<VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
1469 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1470 |res| separate::<VecBrand, _, _>(res),
1471 traverse::<VecBrand, OptionBrand, _, _, _>(p, x),
1472 );
1473
1474 lhs == rhs
1475 }
1476
1477 /// Tests `wither p ≡ map compact <<< traverse p`.
1478 #[quickcheck]
1479 fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1480 let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1481
1482 let lhs = wither::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1483 let rhs = crate::classes::functor::map::<OptionBrand, _, _, _>(
1484 |opt| compact::<VecBrand, _>(opt),
1485 traverse::<VecBrand, OptionBrand, _, _, _>(p, x),
1486 );
1487
1488 lhs == rhs
1489 }
1490
1491 // Edge Cases
1492
1493 /// Tests `compact` on an empty vector.
1494 #[test]
1495 fn compact_empty() {
1496 assert_eq!(compact::<VecBrand, _>(vec![] as Vec<Option<i32>>), vec![]);
1497 }
1498
1499 /// Tests `compact` on a vector with `None`.
1500 #[test]
1501 fn compact_with_none() {
1502 assert_eq!(compact::<VecBrand, _>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1503 }
1504
1505 /// Tests `separate` on an empty vector.
1506 #[test]
1507 fn separate_empty() {
1508 let Pair(oks, errs) = separate::<VecBrand, _, _>(vec![] as Vec<Result<i32, i32>>);
1509 assert_eq!(oks, vec![]);
1510 assert_eq!(errs, vec![]);
1511 }
1512
1513 /// Tests `separate` on a vector with `Ok` and `Err`.
1514 #[test]
1515 fn separate_mixed() {
1516 let Pair(oks, errs) = separate::<VecBrand, _, _>(vec![Ok(1), Err(2), Ok(3)]);
1517 assert_eq!(oks, vec![1, 3]);
1518 assert_eq!(errs, vec![2]);
1519 }
1520
1521 /// Tests `partition_map` on an empty vector.
1522 #[test]
1523 fn partition_map_empty() {
1524 let Pair(oks, errs) =
1525 partition_map::<VecBrand, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1526 assert_eq!(oks, vec![]);
1527 assert_eq!(errs, vec![]);
1528 }
1529
1530 /// Tests `partition` on an empty vector.
1531 #[test]
1532 fn partition_empty() {
1533 let Pair(satisfied, not_satisfied) = partition::<VecBrand, _, _>(|x: i32| x > 0, vec![]);
1534 assert_eq!(satisfied, vec![]);
1535 assert_eq!(not_satisfied, vec![]);
1536 }
1537
1538 /// Tests `filter_map` on an empty vector.
1539 #[test]
1540 fn filter_map_empty() {
1541 assert_eq!(filter_map::<VecBrand, _, _, _>(|x: i32| Some(x), vec![]), vec![]);
1542 }
1543
1544 /// Tests `filter` on an empty vector.
1545 #[test]
1546 fn filter_empty() {
1547 assert_eq!(filter::<VecBrand, _, _>(|x: i32| x > 0, vec![]), vec![]);
1548 }
1549
1550 /// Tests `wilt` on an empty vector.
1551 #[test]
1552 fn wilt_empty() {
1553 let res =
1554 wilt::<VecBrand, OptionBrand, _, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1555 assert_eq!(res, Some(Pair(vec![], vec![])));
1556 }
1557
1558 /// Tests `wither` on an empty vector.
1559 #[test]
1560 fn wither_empty() {
1561 let res = wither::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Some(x)), vec![]);
1562 assert_eq!(res, Some(vec![]));
1563 }
1564}