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}