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