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}