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