fp_library/types/vec.rs
1//! Implementations for [`Vec`].
2
3use crate::{
4 brands::VecBrand,
5 classes::{
6 applicative::Applicative,
7 apply_first::ApplyFirst,
8 apply_second::ApplySecond,
9 clonable_fn::{ApplyClonableFn, ClonableFn},
10 foldable::Foldable,
11 functor::Functor,
12 lift::Lift,
13 monoid::Monoid,
14 pointed::Pointed,
15 semiapplicative::Semiapplicative,
16 semigroup::Semigroup,
17 semimonad::Semimonad,
18 traversable::Traversable,
19 },
20 hkt::{Apply1L1T, Kind1L1T},
21};
22
23impl Kind1L1T for VecBrand {
24 type Output<'a, A: 'a> = Vec<A>;
25}
26
27impl VecBrand {
28 /// Constructs a new vector by prepending a value to an existing vector.
29 ///
30 /// # Type Signature
31 ///
32 /// `forall a. a -> Vec a -> Vec a`
33 ///
34 /// # Parameters
35 ///
36 /// * `head`: A value to prepend to the vector.
37 /// * `tail`: A vector to prepend the value to.
38 ///
39 /// # Returns
40 ///
41 /// A new vector consisting of the `head` element prepended to the `tail` vector.
42 ///
43 /// # Examples
44 ///
45 /// ```
46 /// use fp_library::brands::VecBrand;
47 ///
48 /// let head = 1;
49 /// let tail = vec![2, 3];
50 /// let new_vec = VecBrand::construct(head, tail);
51 /// assert_eq!(new_vec, vec![1, 2, 3]);
52 ///
53 /// let empty_tail = vec![];
54 /// let single_element = VecBrand::construct(42, empty_tail);
55 /// assert_eq!(single_element, vec![42]);
56 /// ```
57 pub fn construct<A>(
58 head: A,
59 tail: Vec<A>,
60 ) -> Vec<A>
61 where
62 A: Clone,
63 {
64 [vec![head], tail].concat()
65 }
66
67 /// Deconstructs a slice into its head element and tail vector.
68 ///
69 /// # Type Signature
70 ///
71 /// `forall a. &[a] -> Option (a, Vec a)`
72 ///
73 /// # Parameters
74 ///
75 /// * `slice`: The vector slice to deconstruct.
76 ///
77 /// # Returns
78 ///
79 /// An [`Option`] containing a tuple of the head element and the remaining tail vector,
80 /// or [`None`] if the slice is empty.
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// use fp_library::brands::VecBrand;
86 ///
87 /// let vec = vec![1, 2, 3];
88 /// let deconstructed = VecBrand::deconstruct(&vec);
89 /// assert_eq!(deconstructed, Some((1, vec![2, 3])));
90 ///
91 /// let empty: Vec<i32> = vec![];
92 /// assert_eq!(VecBrand::deconstruct(&empty), None);
93 /// ```
94 pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
95 where
96 A: Clone,
97 {
98 match slice {
99 [] => None,
100 [head, tail @ ..] => Some((head.clone(), tail.to_vec())),
101 }
102 }
103}
104
105impl Functor for VecBrand {
106 /// Maps a function over the vector.
107 ///
108 /// # Type Signature
109 ///
110 /// `forall a b. Functor Vec => (a -> b, Vec a) -> Vec b`
111 ///
112 /// # Parameters
113 ///
114 /// * `f`: The function to apply to each element.
115 /// * `fa`: The vector to map over.
116 ///
117 /// # Returns
118 ///
119 /// A new vector containing the results of applying the function.
120 ///
121 /// # Examples
122 ///
123 /// ```
124 /// use fp_library::classes::functor::map;
125 /// use fp_library::brands::VecBrand;
126 ///
127 /// assert_eq!(map::<VecBrand, _, _, _>(|x: i32| x * 2, vec![1, 2, 3]), vec![2, 4, 6]);
128 /// ```
129 fn map<'a, A: 'a, B: 'a, F>(
130 f: F,
131 fa: Apply1L1T<'a, Self, A>,
132 ) -> Apply1L1T<'a, Self, B>
133 where
134 F: Fn(A) -> B + 'a,
135 {
136 fa.into_iter().map(f).collect()
137 }
138}
139
140impl Lift for VecBrand {
141 /// Lifts a binary function into the vector context (Cartesian product).
142 ///
143 /// # Type Signature
144 ///
145 /// `forall a b c. Lift Vec => ((a, b) -> c, Vec a, Vec b) -> Vec c`
146 ///
147 /// # Parameters
148 ///
149 /// * `f`: The binary function to apply.
150 /// * `fa`: The first vector.
151 /// * `fb`: The second vector.
152 ///
153 /// # Returns
154 ///
155 /// A new vector containing the results of applying the function to all pairs of elements.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use fp_library::classes::lift::lift2;
161 /// use fp_library::brands::VecBrand;
162 ///
163 /// assert_eq!(
164 /// lift2::<VecBrand, _, _, _, _>(|x, y| x + y, vec![1, 2], vec![10, 20]),
165 /// vec![11, 21, 12, 22]
166 /// );
167 /// ```
168 fn lift2<'a, A, B, C, F>(
169 f: F,
170 fa: Apply1L1T<'a, Self, A>,
171 fb: Apply1L1T<'a, Self, B>,
172 ) -> Apply1L1T<'a, Self, C>
173 where
174 F: Fn(A, B) -> C + 'a,
175 A: Clone + 'a,
176 B: Clone + 'a,
177 C: 'a,
178 {
179 fa.iter().flat_map(|a| fb.iter().map(|b| f(a.clone(), b.clone()))).collect()
180 }
181}
182
183impl Pointed for VecBrand {
184 /// Wraps a value in a vector.
185 ///
186 /// # Type Signature
187 ///
188 /// `forall a. Pointed Vec => a -> Vec a`
189 ///
190 /// # Parameters
191 ///
192 /// * `a`: The value to wrap.
193 ///
194 /// # Returns
195 ///
196 /// A vector containing the single value.
197 ///
198 /// # Examples
199 ///
200 /// ```
201 /// use fp_library::classes::pointed::pure;
202 /// use fp_library::brands::VecBrand;
203 ///
204 /// assert_eq!(pure::<VecBrand, _>(5), vec![5]);
205 /// ```
206 fn pure<'a, A: 'a>(a: A) -> Apply1L1T<'a, Self, A> {
207 vec![a]
208 }
209}
210
211impl ApplyFirst for VecBrand {}
212impl ApplySecond for VecBrand {}
213
214impl Semiapplicative for VecBrand {
215 /// Applies wrapped functions to wrapped values (Cartesian product).
216 ///
217 /// # Type Signature
218 ///
219 /// `forall a b. Semiapplicative Vec => (Vec (a -> b), Vec a) -> Vec b`
220 ///
221 /// # Parameters
222 ///
223 /// * `ff`: The vector containing the functions.
224 /// * `fa`: The vector containing the values.
225 ///
226 /// # Returns
227 ///
228 /// A new vector containing the results of applying each function to each value.
229 ///
230 /// # Examples
231 ///
232 /// ```
233 /// use fp_library::classes::semiapplicative::apply;
234 /// use fp_library::classes::clonable_fn::ClonableFn;
235 /// use fp_library::brands::{VecBrand};
236 /// use fp_library::brands::RcFnBrand;
237 /// use std::rc::Rc;
238 ///
239 /// let funcs = vec![
240 /// <RcFnBrand as ClonableFn>::new(|x: i32| x + 1),
241 /// <RcFnBrand as ClonableFn>::new(|x: i32| x * 2),
242 /// ];
243 /// assert_eq!(apply::<VecBrand, _, _, RcFnBrand>(funcs, vec![1, 2]), vec![2, 3, 2, 4]);
244 /// ```
245 fn apply<'a, A: 'a + Clone, B: 'a, FnBrand: 'a + ClonableFn>(
246 ff: Apply1L1T<'a, Self, ApplyClonableFn<'a, FnBrand, A, B>>,
247 fa: Apply1L1T<'a, Self, A>,
248 ) -> Apply1L1T<'a, Self, B> {
249 ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
250 }
251}
252
253impl Semimonad for VecBrand {
254 /// Chains vector computations (flat_map).
255 ///
256 /// # Type Signature
257 ///
258 /// `forall a b. Semimonad Vec => (Vec a, a -> Vec b) -> Vec b`
259 ///
260 /// # Parameters
261 ///
262 /// * `ma`: The first vector.
263 /// * `f`: The function to apply to each element, returning a vector.
264 ///
265 /// # Returns
266 ///
267 /// A new vector containing the flattened results.
268 ///
269 /// # Examples
270 ///
271 /// ```
272 /// use fp_library::classes::semimonad::bind;
273 /// use fp_library::brands::VecBrand;
274 ///
275 /// assert_eq!(
276 /// bind::<VecBrand, _, _, _>(vec![1, 2], |x| vec![x, x * 2]),
277 /// vec![1, 2, 2, 4]
278 /// );
279 /// ```
280 fn bind<'a, A: 'a, B: 'a, F>(
281 ma: Apply1L1T<'a, Self, A>,
282 f: F,
283 ) -> Apply1L1T<'a, Self, B>
284 where
285 F: Fn(A) -> Apply1L1T<'a, Self, B> + 'a,
286 {
287 ma.into_iter().flat_map(f).collect()
288 }
289}
290
291impl Foldable for VecBrand {
292 /// Folds the vector from the right.
293 ///
294 /// # Type Signature
295 ///
296 /// `forall a b. Foldable Vec => ((a, b) -> b, b, Vec a) -> b`
297 ///
298 /// # Parameters
299 ///
300 /// * `f`: The folding function.
301 /// * `init`: The initial value.
302 /// * `fa`: The vector to fold.
303 ///
304 /// # Returns
305 ///
306 /// The final accumulator value.
307 ///
308 /// # Examples
309 ///
310 /// ```
311 /// use fp_library::classes::foldable::fold_right;
312 /// use fp_library::brands::VecBrand;
313 ///
314 /// assert_eq!(fold_right::<VecBrand, _, _, _>(|x: i32, acc| x + acc, 0, vec![1, 2, 3]), 6);
315 /// ```
316 fn fold_right<'a, A: 'a, B: 'a, F>(
317 f: F,
318 init: B,
319 fa: Apply1L1T<'a, Self, A>,
320 ) -> B
321 where
322 F: Fn(A, B) -> B + 'a,
323 {
324 fa.into_iter().rev().fold(init, |acc, x| f(x, acc))
325 }
326
327 /// Folds the vector from the left.
328 ///
329 /// # Type Signature
330 ///
331 /// `forall a b. Foldable Vec => ((b, a) -> b, b, Vec a) -> b`
332 ///
333 /// # Parameters
334 ///
335 /// * `f`: The folding function.
336 /// * `init`: The initial value.
337 /// * `fa`: The vector to fold.
338 ///
339 /// # Returns
340 ///
341 /// The final accumulator value.
342 ///
343 /// # Examples
344 ///
345 /// ```
346 /// use fp_library::classes::foldable::fold_left;
347 /// use fp_library::brands::VecBrand;
348 ///
349 /// assert_eq!(fold_left::<VecBrand, _, _, _>(|acc, x: i32| acc + x, 0, vec![1, 2, 3]), 6);
350 /// ```
351 fn fold_left<'a, A: 'a, B: 'a, F>(
352 f: F,
353 init: B,
354 fa: Apply1L1T<'a, Self, A>,
355 ) -> B
356 where
357 F: Fn(B, A) -> B + 'a,
358 {
359 fa.into_iter().fold(init, f)
360 }
361
362 /// Maps the values to a monoid and combines them.
363 ///
364 /// # Type Signature
365 ///
366 /// `forall a m. (Foldable Vec, Monoid m) => ((a) -> m, Vec a) -> m`
367 ///
368 /// # Parameters
369 ///
370 /// * `f`: The mapping function.
371 /// * `fa`: The vector to fold.
372 ///
373 /// # Returns
374 ///
375 /// The combined monoid value.
376 ///
377 /// # Examples
378 ///
379 /// ```
380 /// use fp_library::classes::foldable::fold_map;
381 /// use fp_library::brands::VecBrand;
382 /// use fp_library::types::string; // Import to bring Monoid impl for String into scope
383 ///
384 /// assert_eq!(
385 /// fold_map::<VecBrand, _, _, _>(|x: i32| x.to_string(), vec![1, 2, 3]),
386 /// "123".to_string()
387 /// );
388 /// ```
389 fn fold_map<'a, A: 'a, M, F>(
390 f: F,
391 fa: Apply1L1T<'a, Self, A>,
392 ) -> M
393 where
394 M: Monoid + 'a,
395 F: Fn(A) -> M + 'a,
396 {
397 fa.into_iter().map(f).fold(M::empty(), |acc, x| M::append(acc, x))
398 }
399}
400
401impl Traversable for VecBrand {
402 /// Traverses the vector with an applicative function.
403 ///
404 /// # Type Signature
405 ///
406 /// `forall a b f. (Traversable Vec, Applicative f) => (a -> f b, Vec a) -> f (Vec b)`
407 ///
408 /// # Parameters
409 ///
410 /// * `f`: The function to apply.
411 /// * `ta`: The vector to traverse.
412 ///
413 /// # Returns
414 ///
415 /// The vector wrapped in the applicative context.
416 ///
417 /// # Examples
418 ///
419 /// ```
420 /// use fp_library::classes::traversable::traverse;
421 /// use fp_library::brands::{OptionBrand, VecBrand};
422 ///
423 /// assert_eq!(
424 /// traverse::<VecBrand, OptionBrand, _, _, _>(|x| Some(x * 2), vec![1, 2, 3]),
425 /// Some(vec![2, 4, 6])
426 /// );
427 /// ```
428 fn traverse<'a, F: Applicative, A: 'a + Clone, B: 'a + Clone, Func>(
429 f: Func,
430 ta: Apply1L1T<'a, Self, A>,
431 ) -> Apply1L1T<'a, F, Apply1L1T<'a, Self, B>>
432 where
433 Func: Fn(A) -> Apply1L1T<'a, F, B> + 'a,
434 Apply1L1T<'a, Self, B>: Clone,
435 {
436 let len = ta.len();
437 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
438 F::lift2(
439 |mut v, b| {
440 v.push(b);
441 v
442 },
443 acc,
444 f(x),
445 )
446 })
447 }
448
449 /// Sequences a vector of applicative.
450 ///
451 /// # Type Signature
452 ///
453 /// `forall a f. (Traversable Vec, Applicative f) => (Vec (f a)) -> f (Vec a)`
454 ///
455 /// # Parameters
456 ///
457 /// * `ta`: The vector containing the applicative values.
458 ///
459 /// # Returns
460 ///
461 /// The vector wrapped in the applicative context.
462 ///
463 /// # Examples
464 ///
465 /// ```
466 /// use fp_library::classes::traversable::sequence;
467 /// use fp_library::brands::{OptionBrand, VecBrand};
468 ///
469 /// assert_eq!(
470 /// sequence::<VecBrand, OptionBrand, _>(vec![Some(1), Some(2)]),
471 /// Some(vec![1, 2])
472 /// );
473 /// ```
474 fn sequence<'a, F: Applicative, A: 'a + Clone>(
475 ta: Apply1L1T<'a, Self, Apply1L1T<'a, F, A>>
476 ) -> Apply1L1T<'a, F, Apply1L1T<'a, Self, A>>
477 where
478 Apply1L1T<'a, F, A>: Clone,
479 Apply1L1T<'a, Self, A>: Clone,
480 {
481 let len = ta.len();
482 ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
483 F::lift2(
484 |mut v, a| {
485 v.push(a);
486 v
487 },
488 acc,
489 x,
490 )
491 })
492 }
493}
494
495impl<A: Clone> Semigroup for Vec<A> {
496 /// Appends one vector to another.
497 ///
498 /// # Type Signature
499 ///
500 /// `forall a. Semigroup (Vec a) => (Vec a, Vec a) -> Vec a`
501 ///
502 /// # Parameters
503 ///
504 /// * `a`: The first vector.
505 /// * `b`: The second vector.
506 ///
507 /// # Returns
508 ///
509 /// The concatenated vector.
510 ///
511 /// # Examples
512 ///
513 /// ```
514 /// use fp_library::classes::semigroup::append;
515 ///
516 /// assert_eq!(append(vec![1, 2], vec![3, 4]), vec![1, 2, 3, 4]);
517 /// ```
518 fn append(
519 a: Self,
520 b: Self,
521 ) -> Self {
522 [a, b].concat()
523 }
524}
525
526impl<A: Clone> Monoid for Vec<A> {
527 /// Returns an empty vector.
528 ///
529 /// # Type Signature
530 ///
531 /// `forall a. Monoid (Vec a) => () -> Vec a`
532 ///
533 /// # Returns
534 ///
535 /// An empty vector.
536 ///
537 /// # Examples
538 ///
539 /// ```
540 /// use fp_library::classes::monoid::empty;
541 ///
542 /// assert_eq!(empty::<Vec<i32>>(), vec![]);
543 /// ```
544 fn empty() -> Self {
545 Vec::new()
546 }
547}
548
549#[cfg(test)]
550mod tests {
551 use super::*;
552 use crate::{
553 brands::RcFnBrand,
554 classes::{
555 functor::map, monoid::empty, pointed::pure, semiapplicative::apply, semigroup::append,
556 semimonad::bind,
557 },
558 functions::{compose, identity},
559 };
560 use quickcheck_macros::quickcheck;
561
562 // Functor Laws
563
564 /// Tests the identity law for Functor.
565 #[quickcheck]
566 fn functor_identity(x: Vec<i32>) -> bool {
567 map::<VecBrand, _, _, _>(identity, x.clone()) == x
568 }
569
570 /// Tests the composition law for Functor.
571 #[quickcheck]
572 fn functor_composition(x: Vec<i32>) -> bool {
573 let f = |x: i32| x.wrapping_add(1);
574 let g = |x: i32| x.wrapping_mul(2);
575 map::<VecBrand, _, _, _>(compose(f, g), x.clone())
576 == map::<VecBrand, _, _, _>(f, map::<VecBrand, _, _, _>(g, x))
577 }
578
579 // Applicative Laws
580
581 /// Tests the identity law for Applicative.
582 #[quickcheck]
583 fn applicative_identity(v: Vec<i32>) -> bool {
584 apply::<VecBrand, _, _, RcFnBrand>(
585 pure::<VecBrand, _>(<RcFnBrand as ClonableFn>::new(identity)),
586 v.clone(),
587 ) == v
588 }
589
590 /// Tests the homomorphism law for Applicative.
591 #[quickcheck]
592 fn applicative_homomorphism(x: i32) -> bool {
593 let f = |x: i32| x.wrapping_mul(2);
594 apply::<VecBrand, _, _, RcFnBrand>(
595 pure::<VecBrand, _>(<RcFnBrand as ClonableFn>::new(f)),
596 pure::<VecBrand, _>(x),
597 ) == pure::<VecBrand, _>(f(x))
598 }
599
600 /// Tests the composition law for Applicative.
601 #[quickcheck]
602 fn applicative_composition(
603 w: Vec<i32>,
604 u_seeds: Vec<i32>,
605 v_seeds: Vec<i32>,
606 ) -> bool {
607 let u_fns: Vec<_> = u_seeds
608 .iter()
609 .map(|&i| <RcFnBrand as ClonableFn>::new(move |x: i32| x.wrapping_add(i)))
610 .collect();
611 let v_fns: Vec<_> = v_seeds
612 .iter()
613 .map(|&i| <RcFnBrand as ClonableFn>::new(move |x: i32| x.wrapping_mul(i)))
614 .collect();
615
616 // RHS: u <*> (v <*> w)
617 let vw = apply::<VecBrand, _, _, RcFnBrand>(v_fns.clone(), w.clone());
618 let rhs = apply::<VecBrand, _, _, RcFnBrand>(u_fns.clone(), vw);
619
620 // LHS: pure(compose) <*> u <*> v <*> w
621 // equivalent to (u . v) <*> w
622 // We construct (u . v) manually as the cartesian product of compositions
623 let uv_fns: Vec<_> = u_fns
624 .iter()
625 .flat_map(|uf| {
626 v_fns.iter().map(move |vf| {
627 let uf = uf.clone();
628 let vf = vf.clone();
629 <RcFnBrand as ClonableFn>::new(move |x| uf(vf(x)))
630 })
631 })
632 .collect();
633
634 let lhs = apply::<VecBrand, _, _, RcFnBrand>(uv_fns, w);
635
636 lhs == rhs
637 }
638
639 /// Tests the interchange law for Applicative.
640 #[quickcheck]
641 fn applicative_interchange(y: i32) -> bool {
642 // u <*> pure y = pure ($ y) <*> u
643 let f = |x: i32| x.wrapping_mul(2);
644 let u = vec![<RcFnBrand as ClonableFn>::new(f)];
645
646 let lhs = apply::<VecBrand, _, _, RcFnBrand>(u.clone(), pure::<VecBrand, _>(y));
647
648 let rhs_fn = <RcFnBrand as ClonableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
649 let rhs = apply::<VecBrand, _, _, RcFnBrand>(pure::<VecBrand, _>(rhs_fn), u);
650
651 lhs == rhs
652 }
653
654 // Semigroup Laws
655
656 /// Tests the associativity law for Semigroup.
657 #[quickcheck]
658 fn semigroup_associativity(
659 a: Vec<i32>,
660 b: Vec<i32>,
661 c: Vec<i32>,
662 ) -> bool {
663 append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
664 }
665
666 // Monoid Laws
667
668 /// Tests the left identity law for Monoid.
669 #[quickcheck]
670 fn monoid_left_identity(a: Vec<i32>) -> bool {
671 append(empty::<Vec<i32>>(), a.clone()) == a
672 }
673
674 /// Tests the right identity law for Monoid.
675 #[quickcheck]
676 fn monoid_right_identity(a: Vec<i32>) -> bool {
677 append(a.clone(), empty::<Vec<i32>>()) == a
678 }
679
680 // Monad Laws
681
682 /// Tests the left identity law for Monad.
683 #[quickcheck]
684 fn monad_left_identity(a: i32) -> bool {
685 let f = |x: i32| vec![x.wrapping_mul(2)];
686 bind::<VecBrand, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
687 }
688
689 /// Tests the right identity law for Monad.
690 #[quickcheck]
691 fn monad_right_identity(m: Vec<i32>) -> bool {
692 bind::<VecBrand, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
693 }
694
695 /// Tests the associativity law for Monad.
696 #[quickcheck]
697 fn monad_associativity(m: Vec<i32>) -> bool {
698 let f = |x: i32| vec![x.wrapping_mul(2)];
699 let g = |x: i32| vec![x.wrapping_add(1)];
700 bind::<VecBrand, _, _, _>(bind::<VecBrand, _, _, _>(m.clone(), f), g)
701 == bind::<VecBrand, _, _, _>(m, |x| bind::<VecBrand, _, _, _>(f(x), g))
702 }
703
704 // Edge Cases
705
706 /// Tests `map` on an empty vector.
707 #[test]
708 fn map_empty() {
709 assert_eq!(map::<VecBrand, _, _, _>(|x: i32| x + 1, vec![]), vec![]);
710 }
711
712 /// Tests `bind` on an empty vector.
713 #[test]
714 fn bind_empty() {
715 assert_eq!(bind::<VecBrand, _, _, _>(vec![], |x: i32| vec![x + 1]), vec![]);
716 }
717
718 /// Tests `bind` returning an empty vector.
719 #[test]
720 fn bind_returning_empty() {
721 assert_eq!(bind::<VecBrand, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>), vec![]);
722 }
723
724 /// Tests `fold_right` on an empty vector.
725 #[test]
726 fn fold_right_empty() {
727 assert_eq!(
728 crate::classes::foldable::fold_right::<VecBrand, _, _, _>(
729 |x: i32, acc| x + acc,
730 0,
731 vec![]
732 ),
733 0
734 );
735 }
736
737 /// Tests `fold_left` on an empty vector.
738 #[test]
739 fn fold_left_empty() {
740 assert_eq!(
741 crate::classes::foldable::fold_left::<VecBrand, _, _, _>(
742 |acc, x: i32| acc + x,
743 0,
744 vec![]
745 ),
746 0
747 );
748 }
749
750 /// Tests `traverse` on an empty vector.
751 #[test]
752 fn traverse_empty() {
753 use crate::brands::OptionBrand;
754 assert_eq!(
755 crate::classes::traversable::traverse::<VecBrand, OptionBrand, _, _, _>(
756 |x: i32| Some(x + 1),
757 vec![]
758 ),
759 Some(vec![])
760 );
761 }
762
763 /// Tests `traverse` returning an empty vector.
764 #[test]
765 fn traverse_returning_empty() {
766 use crate::brands::OptionBrand;
767 assert_eq!(
768 crate::classes::traversable::traverse::<VecBrand, OptionBrand, _, _, _>(
769 |_: i32| None::<i32>,
770 vec![1, 2, 3]
771 ),
772 None
773 );
774 }
775
776 /// Tests `construct` with an empty tail.
777 #[test]
778 fn construct_empty_tail() {
779 assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
780 }
781
782 /// Tests `deconstruct` on an empty slice.
783 #[test]
784 fn deconstruct_empty() {
785 assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
786 }
787}