Skip to main content

fp_library/types/
option.rs

1//! Functional programming trait implementations for the standard library [`Option`] type.
2//!
3//! Extends `Option` with [`Functor`](crate::classes::Functor), [`Monad`](crate::classes::semimonad::Semimonad), [`Foldable`](crate::classes::Foldable), [`Traversable`](crate::classes::Traversable), [`Filterable`](crate::classes::Filterable), and [`Witherable`](crate::classes::Witherable) instances. The corresponding brand is [`OptionBrand`](crate::brands::OptionBrand).
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::OptionBrand,
11			classes::*,
12			dispatch::Ref,
13			impl_kind,
14			kinds::*,
15		},
16		core::ops::ControlFlow,
17		fp_macros::*,
18	};
19
20	impl_kind! {
21		for OptionBrand {
22			type Of<'a, A: 'a>: 'a = Option<A>;
23		}
24	}
25
26	impl Functor for OptionBrand {
27		/// Maps a function over the value in the option.
28		///
29		/// This method applies a function to the value inside the option, producing a new option with the transformed value. If the option is `None`, it returns `None`.
30		#[document_signature]
31		///
32		#[document_type_parameters(
33			"The lifetime of the value.",
34			"The type of the value inside the option.",
35			"The type of the result of applying the function."
36		)]
37		///
38		#[document_parameters("The function to apply to the value.", "The option to map over.")]
39		///
40		#[document_returns(
41			"A new option containing the result of applying the function, or `None`."
42		)]
43		///
44		#[document_examples]
45		///
46		/// ```
47		/// use fp_library::{
48		/// 	brands::*,
49		/// 	functions::*,
50		/// };
51		///
52		/// let x = Some(5);
53		/// let y = explicit::map::<OptionBrand, _, _, _, _>(|i| i * 2, x);
54		/// assert_eq!(y, Some(10));
55		/// ```
56		fn map<'a, A: 'a, B: 'a>(
57			func: impl Fn(A) -> B + 'a,
58			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
59		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
60			fa.map(func)
61		}
62	}
63
64	impl Lift for OptionBrand {
65		/// Lifts a binary function into the option context.
66		///
67		/// This method lifts a binary function to operate on values within the option context.
68		#[document_signature]
69		///
70		#[document_type_parameters(
71			"The lifetime of the values.",
72			"The type of the first option's value.",
73			"The type of the second option's value.",
74			"The return type of the function."
75		)]
76		///
77		#[document_parameters(
78			"The binary function to apply.",
79			"The first option.",
80			"The second option."
81		)]
82		///
83		#[document_returns("`Some(f(a, b))` if both options are `Some`, otherwise `None`.")]
84		#[document_examples]
85		///
86		/// ```
87		/// use fp_library::{
88		/// 	brands::*,
89		/// 	functions::*,
90		/// };
91		///
92		/// let x = Some(1);
93		/// let y = Some(2);
94		/// let z = explicit::lift2::<OptionBrand, _, _, _, _, _, _>(|a, b| a + b, x, y);
95		/// assert_eq!(z, Some(3));
96		/// ```
97		fn lift2<'a, A, B, C>(
98			func: impl Fn(A, B) -> C + 'a,
99			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
100			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
101		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
102		where
103			A: 'a,
104			B: 'a,
105			C: 'a, {
106			fa.zip(fb).map(|(a, b)| func(a, b))
107		}
108	}
109
110	impl Pointed for OptionBrand {
111		/// Wraps a value in an option.
112		///
113		/// This method wraps a value in an option context.
114		#[document_signature]
115		///
116		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
117		///
118		#[document_parameters("The value to wrap.")]
119		///
120		#[document_returns("`Some(a)`.")]
121		///
122		#[document_examples]
123		///
124		/// ```
125		/// use fp_library::{
126		/// 	brands::OptionBrand,
127		/// 	functions::*,
128		/// };
129		///
130		/// let x = pure::<OptionBrand, _>(5);
131		/// assert_eq!(x, Some(5));
132		/// ```
133		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
134			Some(a)
135		}
136	}
137
138	impl ApplyFirst for OptionBrand {}
139	impl ApplySecond for OptionBrand {}
140
141	impl Semiapplicative for OptionBrand {
142		/// Applies a wrapped function to a wrapped value.
143		///
144		/// This method applies a function wrapped in an option to a value wrapped in an option.
145		#[document_signature]
146		///
147		#[document_type_parameters(
148			"The lifetime of the values.",
149			"The brand of the cloneable function wrapper.",
150			"The type of the input value.",
151			"The type of the output value."
152		)]
153		///
154		#[document_parameters(
155			"The option containing the function.",
156			"The option containing the value."
157		)]
158		///
159		#[document_returns("`Some(f(a))` if both are `Some`, otherwise `None`.")]
160		#[document_examples]
161		///
162		/// ```
163		/// use fp_library::{
164		/// 	brands::*,
165		/// 	classes::*,
166		/// 	functions::*,
167		/// };
168		///
169		/// let f = Some(lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
170		/// let x = Some(5);
171		/// let y = apply(f, x);
172		/// assert_eq!(y, Some(10));
173		/// ```
174		fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
175			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
176			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
177		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
178			match (ff, fa) {
179				(Some(f), Some(a)) => Some(f(a)),
180				_ => None,
181			}
182		}
183	}
184
185	impl Semimonad for OptionBrand {
186		/// Chains option computations.
187		///
188		/// This method chains two option computations, where the second computation depends on the result of the first.
189		#[document_signature]
190		///
191		#[document_type_parameters(
192			"The lifetime of the values.",
193			"The type of the result of the first computation.",
194			"The type of the result of the second computation."
195		)]
196		///
197		#[document_parameters(
198			"The first option.",
199			"The function to apply to the value inside the option."
200		)]
201		///
202		#[document_returns(
203			"The result of applying `f` to the value if `ma` is `Some`, otherwise `None`."
204		)]
205		#[document_examples]
206		///
207		/// ```
208		/// use fp_library::{
209		/// 	brands::OptionBrand,
210		/// 	functions::*,
211		/// };
212		///
213		/// let x = Some(5);
214		/// let y = explicit::bind::<OptionBrand, _, _, _, _>(x, |i| Some(i * 2));
215		/// assert_eq!(y, Some(10));
216		/// ```
217		fn bind<'a, A: 'a, B: 'a>(
218			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
219			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
220		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
221			ma.and_then(func)
222		}
223	}
224
225	impl Alt for OptionBrand {
226		/// Chooses between two options.
227		///
228		/// Returns the first `Some` value, or `None` if both are `None`.
229		#[document_signature]
230		///
231		#[document_type_parameters("The lifetime of the values.", "The type of the value.")]
232		///
233		#[document_parameters("The first option.", "The second option.")]
234		///
235		#[document_returns("The first `Some` value, or `None`.")]
236		#[document_examples]
237		///
238		/// ```
239		/// use fp_library::{
240		/// 	brands::*,
241		/// 	classes::*,
242		/// 	functions::*,
243		/// };
244		///
245		/// assert_eq!(explicit::alt::<OptionBrand, _, _, _>(None, Some(5)), Some(5));
246		/// assert_eq!(explicit::alt::<OptionBrand, _, _, _>(Some(3), Some(5)), Some(3));
247		/// assert_eq!(explicit::alt::<OptionBrand, _, _, _>(None::<i32>, None), None);
248		/// ```
249		fn alt<'a, A: 'a>(
250			fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
251			fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
252		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
253			fa1.or(fa2)
254		}
255	}
256
257	impl RefAlt for OptionBrand {
258		/// Chooses between two options by reference.
259		///
260		/// Returns the first `Some` value (cloned), or `None` if both are `None`.
261		/// This is the by-reference counterpart of [`Alt::alt`] for `Option`,
262		/// borrowing both arguments and cloning the inner value as needed.
263		#[document_signature]
264		///
265		#[document_type_parameters("The lifetime of the values.", "The type of the value.")]
266		///
267		#[document_parameters("The first option.", "The second option.")]
268		///
269		#[document_returns("The first `Some` value (cloned), or `None`.")]
270		#[document_examples]
271		///
272		/// ```
273		/// use fp_library::{
274		/// 	brands::*,
275		/// 	classes::*,
276		/// 	functions::*,
277		/// };
278		///
279		/// assert_eq!(explicit::alt::<OptionBrand, _, _, _>(&None, &Some(5)), Some(5));
280		/// assert_eq!(explicit::alt::<OptionBrand, _, _, _>(&Some(3), &Some(5)), Some(3));
281		/// assert_eq!(explicit::alt::<OptionBrand, _, _, _>(&None::<i32>, &None), None);
282		/// ```
283		fn ref_alt<'a, A: 'a + Clone>(
284			fa1: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
285			fa2: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
286		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
287			fa1.as_ref().or(fa2.as_ref()).cloned()
288		}
289	}
290
291	impl Plus for OptionBrand {
292		/// Returns `None`, the identity element for [`alt`](Alt::alt).
293		#[document_signature]
294		///
295		#[document_type_parameters("The lifetime of the value.", "The type of the value.")]
296		///
297		#[document_returns("`None`.")]
298		#[document_examples]
299		///
300		/// ```
301		/// use fp_library::{
302		/// 	brands::*,
303		/// 	functions::*,
304		/// };
305		///
306		/// let x: Option<i32> = plus_empty::<OptionBrand, i32>();
307		/// assert_eq!(x, None);
308		/// ```
309		fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
310			None
311		}
312	}
313
314	impl Foldable for OptionBrand {
315		/// Folds the option from the right.
316		///
317		/// This method performs a right-associative fold of the option. If the option is `Some(a)`, it applies the function to `a` and the initial value. If `None`, it returns the initial value.
318		#[document_signature]
319		///
320		#[document_type_parameters(
321			"The lifetime of the values.",
322			"The brand of the cloneable function to use.",
323			"The type of the elements in the structure.",
324			"The type of the accumulator."
325		)]
326		///
327		#[document_parameters("The folding function.", "The initial value.", "The option to fold.")]
328		///
329		#[document_returns("`func(a, initial)` if `fa` is `Some(a)`, otherwise `initial`.")]
330		///
331		#[document_examples]
332		///
333		/// ```
334		/// use fp_library::{
335		/// 	brands::*,
336		/// 	functions::*,
337		/// };
338		///
339		/// let x = Some(5);
340		/// let y = explicit::fold_right::<RcFnBrand, OptionBrand, _, _, _, _>(|a, b| a + b, 10, x);
341		/// assert_eq!(y, 15);
342		/// ```
343		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
344			func: impl Fn(A, B) -> B + 'a,
345			initial: B,
346			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
347		) -> B
348		where
349			FnBrand: CloneFn + 'a, {
350			match fa {
351				Some(a) => func(a, initial),
352				None => initial,
353			}
354		}
355
356		/// Folds the option from the left.
357		///
358		/// This method performs a left-associative fold of the option. If the option is `Some(a)`, it applies the function to the initial value and `a`. If `None`, it returns the initial value.
359		#[document_signature]
360		///
361		#[document_type_parameters(
362			"The lifetime of the values.",
363			"The brand of the cloneable function to use.",
364			"The type of the elements in the structure.",
365			"The type of the accumulator."
366		)]
367		///
368		#[document_parameters(
369			"The function to apply to the accumulator and each element.",
370			"The initial value of the accumulator.",
371			"The option to fold."
372		)]
373		///
374		#[document_returns("`f(initial, a)` if `fa` is `Some(a)`, otherwise `initial`.")]
375		#[document_examples]
376		///
377		/// ```
378		/// use fp_library::{
379		/// 	brands::*,
380		/// 	functions::*,
381		/// };
382		///
383		/// let x = Some(5);
384		/// let y = explicit::fold_left::<RcFnBrand, OptionBrand, _, _, _, _>(|b, a| b + a, 10, x);
385		/// assert_eq!(y, 15);
386		/// ```
387		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
388			func: impl Fn(B, A) -> B + 'a,
389			initial: B,
390			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
391		) -> B
392		where
393			FnBrand: CloneFn + 'a, {
394			match fa {
395				Some(a) => func(initial, a),
396				None => initial,
397			}
398		}
399
400		/// Maps the value to a monoid and returns it, or returns empty.
401		///
402		/// This method maps the element of the option to a monoid. If the option is `None`, it returns the monoid's identity element.
403		#[document_signature]
404		///
405		#[document_type_parameters(
406			"The lifetime of the values.",
407			"The brand of the cloneable function to use.",
408			"The type of the elements in the structure.",
409			"The type of the monoid."
410		)]
411		///
412		#[document_parameters("The mapping function.", "The option to fold.")]
413		///
414		#[document_returns("`func(a)` if `fa` is `Some(a)`, otherwise `M::empty()`.")]
415		///
416		#[document_examples]
417		///
418		/// ```
419		/// use fp_library::{
420		/// 	brands::*,
421		/// 	functions::*,
422		/// };
423		///
424		/// let x = Some(5);
425		/// let y = explicit::fold_map::<RcFnBrand, OptionBrand, _, _, _, _>(|a: i32| a.to_string(), x);
426		/// assert_eq!(y, "5".to_string());
427		/// ```
428		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
429			func: impl Fn(A) -> M + 'a,
430			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
431		) -> M
432		where
433			M: Monoid + 'a,
434			FnBrand: CloneFn + 'a, {
435			match fa {
436				Some(a) => func(a),
437				None => M::empty(),
438			}
439		}
440	}
441
442	impl Traversable for OptionBrand {
443		/// Traverses the option with an applicative function.
444		///
445		/// This method maps the element of the option to a computation, evaluates it, and wraps the result in the applicative context. If `None`, it returns `pure(None)`.
446		#[document_signature]
447		///
448		#[document_type_parameters(
449			"The lifetime of the values.",
450			"The type of the elements in the traversable structure.",
451			"The type of the elements in the resulting traversable structure.",
452			"The applicative context."
453		)]
454		///
455		#[document_parameters(
456			"The function to apply to each element, returning a value in an applicative context.",
457			"The option to traverse."
458		)]
459		///
460		#[document_returns("The option wrapped in the applicative context.")]
461		#[document_examples]
462		///
463		/// ```
464		/// use fp_library::{
465		/// 	brands::*,
466		/// 	functions::*,
467		/// };
468		///
469		/// let x = Some(5);
470		/// let y =
471		/// 	explicit::traverse::<RcFnBrand, OptionBrand, _, _, OptionBrand, _, _>(|a| Some(a * 2), x);
472		/// assert_eq!(y, Some(Some(10)));
473		/// ```
474		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
475			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
476			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
477		) -> 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>)>)
478		where
479			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
480			match ta {
481				Some(a) => F::map(|b| Some(b), func(a)),
482				None => F::pure(None),
483			}
484		}
485
486		/// Sequences an option of applicative.
487		///
488		/// This method evaluates the computation inside the option and wraps the result in the applicative context. If `None`, it returns `pure(None)`.
489		#[document_signature]
490		///
491		#[document_type_parameters(
492			"The lifetime of the values.",
493			"The type of the elements in the traversable structure.",
494			"The applicative context."
495		)]
496		///
497		#[document_parameters("The option containing the applicative value.")]
498		///
499		#[document_returns("The result of the traversal.")]
500		///
501		/// # Returns
502		///
503		/// The option wrapped in the applicative context.
504		#[document_examples]
505		///
506		/// ```
507		/// use fp_library::{
508		/// 	brands::OptionBrand,
509		/// 	functions::*,
510		/// };
511		///
512		/// let x = Some(Some(5));
513		/// let y = sequence::<OptionBrand, _, OptionBrand>(x);
514		/// assert_eq!(y, Some(Some(5)));
515		/// ```
516		fn sequence<'a, A: 'a + Clone, F: Applicative>(
517			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>)>)
518		) -> 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>)>)
519		where
520			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
521			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
522			match ta {
523				Some(fa) => F::map(|a| Some(a), fa),
524				None => F::pure(None),
525			}
526		}
527	}
528
529	impl WithIndex for OptionBrand {
530		type Index = ();
531	}
532
533	impl FunctorWithIndex for OptionBrand {
534		/// Maps a function over the value in the option, providing the index `()`.
535		#[document_signature]
536		#[document_type_parameters(
537			"The lifetime of the value.",
538			"The type of the value inside the option.",
539			"The type of the result of applying the function."
540		)]
541		#[document_parameters(
542			"The function to apply to the value and its index.",
543			"The option to map over."
544		)]
545		#[document_returns(
546			"A new option containing the result of applying the function, or `None`."
547		)]
548		#[document_examples]
549		///
550		/// ```
551		/// use fp_library::{
552		/// 	brands::OptionBrand,
553		/// 	classes::functor_with_index::FunctorWithIndex,
554		/// 	functions::*,
555		/// };
556		/// let x = Some(5);
557		/// let y = <OptionBrand as FunctorWithIndex>::map_with_index(|_, i| i * 2, x);
558		/// assert_eq!(y, Some(10));
559		/// ```
560		fn map_with_index<'a, A: 'a, B: 'a>(
561			f: impl Fn((), A) -> B + 'a,
562			fa: Option<A>,
563		) -> Option<B> {
564			fa.map(|a| f((), a))
565		}
566	}
567
568	impl FoldableWithIndex for OptionBrand {
569		/// Folds the option using a monoid, providing the index `()`.
570		#[document_signature]
571		#[document_type_parameters(
572			"The lifetime of the value.",
573			"The brand of the cloneable function to use.",
574			"The type of the value inside the option.",
575			"The monoid type."
576		)]
577		#[document_parameters(
578			"The function to apply to the value and its index.",
579			"The option to fold."
580		)]
581		#[document_returns("The monoid value.")]
582		#[document_examples]
583		///
584		/// ```
585		/// use fp_library::{
586		/// 	brands::*,
587		/// 	classes::foldable_with_index::FoldableWithIndex,
588		/// 	functions::*,
589		/// };
590		/// let x = Some(5);
591		/// let y = <OptionBrand as FoldableWithIndex>::fold_map_with_index::<RcFnBrand, _, _>(
592		/// 	|_, i: i32| i.to_string(),
593		/// 	x,
594		/// );
595		/// assert_eq!(y, "5".to_string());
596		/// ```
597		fn fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
598			f: impl Fn((), A) -> R + 'a,
599			fa: Option<A>,
600		) -> R
601		where
602			FnBrand: LiftFn + 'a, {
603			match fa {
604				Some(a) => f((), a),
605				None => R::empty(),
606			}
607		}
608	}
609
610	impl TraversableWithIndex for OptionBrand {
611		/// Traverses the option with an applicative function, providing the index `()`.
612		#[document_signature]
613		#[document_type_parameters(
614			"The lifetime of the value.",
615			"The type of the value inside the option.",
616			"The type of the result.",
617			"The applicative context."
618		)]
619		#[document_parameters(
620			"The function to apply to the value and its index, returning a value in an applicative context.",
621			"The option to traverse."
622		)]
623		#[document_returns("The option wrapped in the applicative context.")]
624		#[document_examples]
625		///
626		/// ```
627		/// use fp_library::{
628		/// 	brands::OptionBrand,
629		/// 	classes::traversable_with_index::TraversableWithIndex,
630		/// 	functions::*,
631		/// };
632		/// let x = Some(5);
633		/// let y = <OptionBrand as TraversableWithIndex>::traverse_with_index::<i32, i32, OptionBrand>(
634		/// 	|_, i| Some(i * 2),
635		/// 	x,
636		/// );
637		/// assert_eq!(y, Some(Some(10)));
638		/// ```
639		fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
640			f: impl Fn((), A) -> M::Of<'a, B> + 'a,
641			ta: Option<A>,
642		) -> M::Of<'a, Option<B>> {
643			match ta {
644				Some(a) => M::map(|b| Some(b), f((), a)),
645				None => M::pure(None),
646			}
647		}
648	}
649
650	impl Compactable for OptionBrand {
651		/// Compacts a nested option.
652		///
653		/// This method flattens a nested option.
654		#[document_signature]
655		///
656		#[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
657		///
658		#[document_parameters("The nested option.")]
659		///
660		#[document_returns("The flattened option.")]
661		///
662		#[document_examples]
663		///
664		/// ```
665		/// use fp_library::{
666		/// 	brands::OptionBrand,
667		/// 	functions::*,
668		/// };
669		///
670		/// let x = Some(Some(5));
671		/// let y = explicit::compact::<OptionBrand, _, _, _>(x);
672		/// assert_eq!(y, Some(5));
673		/// ```
674		fn compact<'a, A: 'a>(
675			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
676			'a,
677			Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
678		>)
679		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
680			fa.flatten()
681		}
682
683		/// Separates an option of result.
684		///
685		/// This method separates an option of result into a pair of options.
686		#[document_signature]
687		///
688		#[document_type_parameters(
689			"The lifetime of the values.",
690			"The type of the error value.",
691			"The type of the success value."
692		)]
693		///
694		#[document_parameters("The option of result.")]
695		///
696		#[document_returns("A pair of options.")]
697		///
698		#[document_examples]
699		///
700		/// ```
701		/// use fp_library::{
702		/// 	brands::*,
703		/// 	functions::*,
704		/// };
705		///
706		/// let x: Option<Result<i32, &str>> = Some(Ok(5));
707		/// let (errs, oks) = explicit::separate::<OptionBrand, _, _, _, _>(x);
708		/// assert_eq!(oks, Some(5));
709		/// assert_eq!(errs, None);
710		/// ```
711		fn separate<'a, E: 'a, O: 'a>(
712			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
713		) -> (
714			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
715			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
716		) {
717			match fa {
718				Some(Ok(o)) => (None, Some(o)),
719				Some(Err(e)) => (Some(e), None),
720				None => (None, None),
721			}
722		}
723	}
724
725	impl RefCompactable for OptionBrand {
726		/// Compacts a borrowed nested option by reference.
727		///
728		/// Flattens a borrowed `Option<Option<A>>` into an `Option<A>`,
729		/// cloning the inner value if present.
730		#[document_signature]
731		///
732		#[document_type_parameters(
733			"The lifetime of the values.",
734			"The type of the elements. Must be [`Clone`] because elements are extracted from a borrowed container."
735		)]
736		///
737		#[document_parameters("A reference to the nested option.")]
738		///
739		#[document_returns("The flattened option with the inner value cloned, or [`None`].")]
740		///
741		#[document_examples]
742		///
743		/// ```
744		/// use fp_library::{
745		/// 	brands::OptionBrand,
746		/// 	functions::*,
747		/// };
748		///
749		/// let x = Some(Some(5));
750		/// let y = explicit::compact::<OptionBrand, _, _, _>(&x);
751		/// assert_eq!(y, Some(5));
752		///
753		/// let z: Option<Option<i32>> = Some(None);
754		/// let w = explicit::compact::<OptionBrand, _, _, _>(&z);
755		/// assert_eq!(w, None);
756		/// ```
757		fn ref_compact<'a, A: 'a + Clone>(
758			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<A>>)
759		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
760			match fa {
761				Some(Some(a)) => Some(a.clone()),
762				_ => None,
763			}
764		}
765
766		/// Separates a borrowed option of result by reference.
767		///
768		/// Splits a borrowed `Option<Result<O, E>>` into a pair of options,
769		/// cloning the inner value. The first element contains the error if
770		/// present, the second contains the success value.
771		#[document_signature]
772		///
773		#[document_type_parameters(
774			"The lifetime of the values.",
775			"The type of the error value. Must be [`Clone`] because elements are extracted from a borrowed container.",
776			"The type of the success value. Must be [`Clone`] because elements are extracted from a borrowed container."
777		)]
778		///
779		#[document_parameters("A reference to the option of result.")]
780		///
781		#[document_returns(
782			"A pair of options: the first containing the cloned error, the second containing the cloned success value."
783		)]
784		///
785		#[document_examples]
786		///
787		/// ```
788		/// use fp_library::{
789		/// 	brands::*,
790		/// 	functions::*,
791		/// };
792		///
793		/// let x: Option<Result<i32, &str>> = Some(Ok(5));
794		/// let (errs, oks) = explicit::separate::<OptionBrand, _, _, _, _>(&x);
795		/// assert_eq!(oks, Some(5));
796		/// assert_eq!(errs, None);
797		///
798		/// let y: Option<Result<i32, &str>> = Some(Err("bad"));
799		/// let (errs, oks) = explicit::separate::<OptionBrand, _, _, _, _>(&y);
800		/// assert_eq!(oks, None);
801		/// assert_eq!(errs, Some("bad"));
802		/// ```
803		fn ref_separate<'a, E: 'a + Clone, O: 'a + Clone>(
804			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
805		) -> (
806			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
807			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
808		) {
809			match fa {
810				Some(Ok(o)) => (None, Some(o.clone())),
811				Some(Err(e)) => (Some(e.clone()), None),
812				None => (None, None),
813			}
814		}
815	}
816
817	impl Filterable for OptionBrand {
818		/// Partitions an option based on a function that returns a result.
819		///
820		/// This method partitions an option based on a function that returns a result.
821		#[document_signature]
822		///
823		#[document_type_parameters(
824			"The lifetime of the values.",
825			"The type of the input value.",
826			"The type of the error value.",
827			"The type of the success value."
828		)]
829		///
830		#[document_parameters("The function to apply.", "The option to partition.")]
831		///
832		#[document_returns("A pair of options.")]
833		///
834		#[document_examples]
835		///
836		/// ```
837		/// use fp_library::{
838		/// 	brands::*,
839		/// 	functions::*,
840		/// };
841		///
842		/// let x = Some(5);
843		/// let (errs, oks) = explicit::partition_map::<OptionBrand, _, _, _, _, _>(
844		/// 	|a| if a > 2 { Ok(a) } else { Err(a) },
845		/// 	x,
846		/// );
847		/// assert_eq!(oks, Some(5));
848		/// assert_eq!(errs, None);
849		/// ```
850		fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
851			func: impl Fn(A) -> Result<O, E> + 'a,
852			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
853		) -> (
854			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
855			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
856		) {
857			match fa {
858				Some(a) => match func(a) {
859					Ok(o) => (None, Some(o)),
860					Err(e) => (Some(e), None),
861				},
862				None => (None, None),
863			}
864		}
865
866		/// Partitions an option based on a predicate.
867		///
868		/// This method partitions an option based on a predicate.
869		#[document_signature]
870		///
871		#[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
872		///
873		#[document_parameters("The predicate.", "The option to partition.")]
874		///
875		#[document_returns("A pair of options.")]
876		///
877		#[document_examples]
878		///
879		/// ```
880		/// use fp_library::{
881		/// 	brands::*,
882		/// 	functions::*,
883		/// };
884		///
885		/// let x = Some(5);
886		/// let (not_satisfied, satisfied) = explicit::partition::<OptionBrand, _, _, _>(|a| a > 2, x);
887		/// assert_eq!(satisfied, Some(5));
888		/// assert_eq!(not_satisfied, None);
889		/// ```
890		fn partition<'a, A: 'a + Clone>(
891			func: impl Fn(A) -> bool + 'a,
892			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
893		) -> (
894			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
895			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
896		) {
897			match fa {
898				Some(a) =>
899					if func(a.clone()) {
900						(None, Some(a))
901					} else {
902						(Some(a), None)
903					},
904				None => (None, None),
905			}
906		}
907
908		/// Maps a function over an option and filters out `None` results.
909		///
910		/// This method maps a function over an option and filters out `None` results.
911		#[document_signature]
912		///
913		#[document_type_parameters(
914			"The lifetime of the values.",
915			"The type of the input value.",
916			"The type of the result of applying the function."
917		)]
918		///
919		#[document_parameters("The function to apply.", "The option to filter and map.")]
920		///
921		#[document_returns("The filtered and mapped option.")]
922		///
923		#[document_examples]
924		///
925		/// ```
926		/// use fp_library::{
927		/// 	brands::OptionBrand,
928		/// 	functions::*,
929		/// };
930		///
931		/// let x = Some(5);
932		/// let y = explicit::filter_map::<OptionBrand, _, _, _, _>(
933		/// 	|a| if a > 2 { Some(a * 2) } else { None },
934		/// 	x,
935		/// );
936		/// assert_eq!(y, Some(10));
937		/// ```
938		fn filter_map<'a, A: 'a, B: 'a>(
939			func: impl Fn(A) -> Option<B> + 'a,
940			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
941		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
942			fa.and_then(func)
943		}
944
945		/// Filters an option based on a predicate.
946		///
947		/// This method filters an option based on a predicate.
948		#[document_signature]
949		///
950		#[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
951		///
952		#[document_parameters("The predicate.", "The option to filter.")]
953		///
954		#[document_returns("The filtered option.")]
955		///
956		#[document_examples]
957		///
958		/// ```
959		/// use fp_library::{
960		/// 	brands::OptionBrand,
961		/// 	functions::*,
962		/// };
963		///
964		/// let x = Some(5);
965		/// let y = explicit::filter::<OptionBrand, _, _, _>(|a| a > 2, x);
966		/// assert_eq!(y, Some(5));
967		/// ```
968		fn filter<'a, A: 'a + Clone>(
969			func: impl Fn(A) -> bool + 'a,
970			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
971		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
972			fa.filter(|a| func(a.clone()))
973		}
974	}
975
976	impl Witherable for OptionBrand {
977		/// Partitions an option based on a function that returns a result in an applicative context.
978		///
979		/// This method partitions an option based on a function that returns a result in an applicative context.
980		#[document_signature]
981		///
982		#[document_type_parameters(
983			"The lifetime of the values.",
984			"The applicative context.",
985			"The type of the elements in the input structure.",
986			"The type of the error values.",
987			"The type of the success values."
988		)]
989		///
990		#[document_parameters(
991			"The function to apply to each element, returning a `Result` in an applicative context.",
992			"The option to partition."
993		)]
994		///
995		#[document_returns("The partitioned option wrapped in the applicative context.")]
996		#[document_examples]
997		///
998		/// ```
999		/// use fp_library::{
1000		/// 	brands::*,
1001		/// 	functions::*,
1002		/// };
1003		///
1004		/// let x = Some(5);
1005		/// let y = explicit::wilt::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _, _>(
1006		/// 	|a| Some(if a > 2 { Ok(a) } else { Err(a) }),
1007		/// 	x,
1008		/// );
1009		/// assert_eq!(y, Some((None, Some(5))));
1010		/// ```
1011		fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1012			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1013			+ 'a,
1014			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1015		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1016		'a,
1017		(
1018			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1019			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1020		),
1021	>)
1022		where
1023			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1024			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1025			match ta {
1026				Some(a) => M::map(
1027					|res| match res {
1028						Ok(o) => (None, Some(o)),
1029						Err(e) => (Some(e), None),
1030					},
1031					func(a),
1032				),
1033				None => M::pure((None, None)),
1034			}
1035		}
1036
1037		/// Maps a function over an option and filters out `None` results in an applicative context.
1038		///
1039		/// This method maps a function over an option and filters out `None` results in an applicative context.
1040		#[document_signature]
1041		///
1042		#[document_type_parameters(
1043			"The lifetime of the values.",
1044			"The applicative context.",
1045			"The type of the elements in the input structure.",
1046			"The type of the result of applying the function."
1047		)]
1048		///
1049		#[document_parameters(
1050			"The function to apply to each element, returning an `Option` in an applicative context.",
1051			"The option to filter and map."
1052		)]
1053		///
1054		#[document_returns("The filtered and mapped option wrapped in the applicative context.")]
1055		#[document_examples]
1056		///
1057		/// ```
1058		/// use fp_library::{
1059		/// 	brands::*,
1060		/// 	functions::*,
1061		/// };
1062		///
1063		/// let x = Some(5);
1064		/// let y = explicit::wither::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _>(
1065		/// 	|a| Some(if a > 2 { Some(a * 2) } else { None }),
1066		/// 	x,
1067		/// );
1068		/// assert_eq!(y, Some(Some(10)));
1069		/// ```
1070		fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1071			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1072			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1073		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1074		'a,
1075		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1076	>)
1077		where
1078			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1079			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1080			match ta {
1081				Some(a) => func(a),
1082				None => M::pure(None),
1083			}
1084		}
1085	}
1086
1087	impl MonadRec for OptionBrand {
1088		/// Performs tail-recursive monadic computation over [`Option`].
1089		///
1090		/// Iteratively applies the step function. If the function returns [`None`],
1091		/// the computation short-circuits. If it returns `Some(ControlFlow::Continue(a))`, the
1092		/// loop continues with the new state. If it returns `Some(ControlFlow::Break(b))`,
1093		/// the computation completes with `Some(b)`.
1094		#[document_signature]
1095		///
1096		#[document_type_parameters(
1097			"The lifetime of the computation.",
1098			"The type of the initial value and loop state.",
1099			"The type of the result."
1100		)]
1101		///
1102		#[document_parameters("The step function.", "The initial value.")]
1103		///
1104		#[document_returns(
1105			"The result of the computation, or `None` if the step function returned `None`."
1106		)]
1107		///
1108		#[document_examples]
1109		///
1110		/// ```
1111		/// use {
1112		/// 	core::ops::ControlFlow,
1113		/// 	fp_library::{
1114		/// 		brands::*,
1115		/// 		functions::*,
1116		/// 		types::*,
1117		/// 	},
1118		/// };
1119		///
1120		/// let result = tail_rec_m::<OptionBrand, _, _>(
1121		/// 	|n| {
1122		/// 		if n < 10 { Some(ControlFlow::Continue(n + 1)) } else { Some(ControlFlow::Break(n)) }
1123		/// 	},
1124		/// 	0,
1125		/// );
1126		/// assert_eq!(result, Some(10));
1127		/// ```
1128		fn tail_rec_m<'a, A: 'a, B: 'a>(
1129			func: impl Fn(
1130				A,
1131			)
1132				-> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1133			+ 'a,
1134			initial: A,
1135		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1136			let mut current = initial;
1137			loop {
1138				match func(current) {
1139					None => return None,
1140					Some(ControlFlow::Continue(next)) => current = next,
1141					Some(ControlFlow::Break(b)) => return Some(b),
1142				}
1143			}
1144		}
1145	}
1146
1147	// -- By-reference trait implementations --
1148
1149	impl RefFunctor for OptionBrand {
1150		/// Maps a function over the option by reference.
1151		#[document_signature]
1152		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1153		#[document_parameters("The function.", "The option.")]
1154		#[document_returns("The mapped option.")]
1155		#[document_examples]
1156		///
1157		/// ```
1158		/// use fp_library::{
1159		/// 	brands::*,
1160		/// 	functions::*,
1161		/// };
1162		/// assert_eq!(explicit::map::<OptionBrand, _, _, _, _>(|x: &i32| *x * 2, &Some(5)), Some(10));
1163		/// ```
1164		fn ref_map<'a, A: 'a, B: 'a>(
1165			func: impl Fn(&A) -> B + 'a,
1166			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1167		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1168			fa.as_ref().map(func)
1169		}
1170	}
1171
1172	impl RefFoldable for OptionBrand {
1173		/// Folds the option by reference.
1174		#[document_signature]
1175		#[document_type_parameters(
1176			"The lifetime.",
1177			"The brand.",
1178			"The element type.",
1179			"The monoid type."
1180		)]
1181		#[document_parameters("The mapping function.", "The option.")]
1182		#[document_returns("The monoid value.")]
1183		#[document_examples]
1184		///
1185		/// ```
1186		/// use fp_library::{
1187		/// 	brands::*,
1188		/// 	functions::*,
1189		/// };
1190		/// let result =
1191		/// 	explicit::fold_map::<RcFnBrand, OptionBrand, _, _, _, _>(|x: &i32| x.to_string(), &Some(5));
1192		/// assert_eq!(result, "5");
1193		/// ```
1194		fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
1195			func: impl Fn(&A) -> M + 'a,
1196			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1197		) -> M
1198		where
1199			FnBrand: LiftFn + 'a,
1200			M: Monoid + 'a, {
1201			match fa {
1202				Some(a) => func(a),
1203				None => Monoid::empty(),
1204			}
1205		}
1206	}
1207
1208	impl RefFilterable for OptionBrand {
1209		/// Filters and maps the option by reference.
1210		#[document_signature]
1211		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1212		#[document_parameters("The function.", "The option.")]
1213		#[document_returns("The filtered option.")]
1214		#[document_examples]
1215		///
1216		/// ```
1217		/// use fp_library::{
1218		/// 	brands::*,
1219		/// 	functions::*,
1220		/// };
1221		/// let result = explicit::filter_map::<OptionBrand, _, _, _, _>(
1222		/// 	|x: &i32| if *x > 3 { Some(*x) } else { None },
1223		/// 	&Some(5),
1224		/// );
1225		/// assert_eq!(result, Some(5));
1226		/// ```
1227		fn ref_filter_map<'a, A: 'a, B: 'a>(
1228			func: impl Fn(&A) -> Option<B> + 'a,
1229			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1230		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1231			fa.as_ref().and_then(func)
1232		}
1233	}
1234
1235	impl RefTraversable for OptionBrand {
1236		/// Traverses the option by reference.
1237		#[document_signature]
1238		#[document_type_parameters(
1239			"The lifetime.",
1240			"The brand.",
1241			"The input type.",
1242			"The output type.",
1243			"The applicative."
1244		)]
1245		#[document_parameters("The function.", "The option.")]
1246		#[document_returns("The traversed result.")]
1247		#[document_examples]
1248		///
1249		/// ```
1250		/// use fp_library::{
1251		/// 	brands::*,
1252		/// 	functions::*,
1253		/// };
1254		/// let result: Vec<Option<String>> = ref_traverse::<OptionBrand, RcFnBrand, _, _, VecBrand>(
1255		/// 	|x: &i32| vec![x.to_string()],
1256		/// 	&Some(5),
1257		/// );
1258		/// assert_eq!(result, vec![Some("5".to_string())]);
1259		/// ```
1260		fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1261			func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1262			ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1263		) -> 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>)>)
1264		where
1265			FnBrand: LiftFn + 'a,
1266			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1267			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1268			match ta {
1269				Some(a) => F::map(|b| Some(b), func(a)),
1270				None => F::pure(None),
1271			}
1272		}
1273	}
1274
1275	impl RefWitherable for OptionBrand {}
1276
1277	impl RefFunctorWithIndex for OptionBrand {
1278		/// Maps by reference with index (always `()`).
1279		#[document_signature]
1280		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1281		#[document_parameters("The function.", "The option.")]
1282		#[document_returns("The mapped option.")]
1283		#[document_examples]
1284		///
1285		/// ```
1286		/// use fp_library::{
1287		/// 	brands::*,
1288		/// 	functions::*,
1289		/// };
1290		/// assert_eq!(
1291		/// 	explicit::map_with_index::<OptionBrand, _, _, _, _>(|(), x: &i32| *x * 2, &Some(5)),
1292		/// 	Some(10),
1293		/// );
1294		/// ```
1295		fn ref_map_with_index<'a, A: 'a, B: 'a>(
1296			func: impl Fn((), &A) -> B + 'a,
1297			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1298		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1299			fa.as_ref().map(|a| func((), a))
1300		}
1301	}
1302
1303	impl RefFoldableWithIndex for OptionBrand {
1304		/// Folds by reference with index (always `()`).
1305		#[document_signature]
1306		#[document_type_parameters(
1307			"The lifetime.",
1308			"The brand of the cloneable function.",
1309			"The element type.",
1310			"The monoid type."
1311		)]
1312		#[document_parameters("The function.", "The option.")]
1313		#[document_returns("The monoid value.")]
1314		#[document_examples]
1315		///
1316		/// ```
1317		/// use fp_library::{
1318		/// 	brands::*,
1319		/// 	functions::*,
1320		/// };
1321		/// let result = explicit::fold_map_with_index::<RcFnBrand, OptionBrand, _, _, _, _>(
1322		/// 	|(), x: &i32| x.to_string(),
1323		/// 	&Some(5),
1324		/// );
1325		/// assert_eq!(result, "5");
1326		/// ```
1327		fn ref_fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
1328			func: impl Fn((), &A) -> R + 'a,
1329			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1330		) -> R
1331		where
1332			FnBrand: LiftFn + 'a, {
1333			match fa {
1334				Some(a) => func((), a),
1335				None => Monoid::empty(),
1336			}
1337		}
1338	}
1339
1340	impl RefTraversableWithIndex for OptionBrand {
1341		/// Traverses by reference with index (always `()`).
1342		#[document_signature]
1343		#[document_type_parameters(
1344			"The lifetime.",
1345			"The input type.",
1346			"The output type.",
1347			"The applicative."
1348		)]
1349		#[document_parameters("The function.", "The option.")]
1350		#[document_returns("The traversed result.")]
1351		#[document_examples]
1352		///
1353		/// ```
1354		/// use fp_library::{
1355		/// 	brands::*,
1356		/// 	functions::*,
1357		/// };
1358		/// let result: Vec<Option<String>> =
1359		/// 	explicit::traverse_with_index::<RcFnBrand, OptionBrand, _, _, VecBrand, _, _>(
1360		/// 		|(), x: &i32| vec![x.to_string()],
1361		/// 		&Some(5),
1362		/// 	);
1363		/// assert_eq!(result, vec![Some("5".to_string())]);
1364		/// ```
1365		fn ref_traverse_with_index<'a, A: 'a + Clone, B: 'a + Clone, M: Applicative>(
1366			f: impl Fn((), &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1367			ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1368		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
1369		where
1370			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1371			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1372			match ta {
1373				Some(a) => M::map(|b| Some(b), f((), a)),
1374				None => M::pure(None),
1375			}
1376		}
1377	}
1378
1379	// -- By-reference monadic trait implementations --
1380
1381	impl RefPointed for OptionBrand {
1382		/// Creates a `Some` from a reference by cloning.
1383		#[document_signature]
1384		#[document_type_parameters("The lifetime of the value.", "The type of the value.")]
1385		#[document_parameters("The reference to the value to wrap.")]
1386		#[document_returns("A `Some` containing a clone of the value.")]
1387		#[document_examples]
1388		///
1389		/// ```
1390		/// use fp_library::{
1391		/// 	brands::*,
1392		/// 	functions::*,
1393		/// };
1394		///
1395		/// let x = 42;
1396		/// let result: Option<i32> = ref_pure::<OptionBrand, _>(&x);
1397		/// assert_eq!(result, Some(42));
1398		/// ```
1399		fn ref_pure<'a, A: Clone + 'a>(
1400			a: &A
1401		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1402			Some(a.clone())
1403		}
1404	}
1405
1406	impl RefLift for OptionBrand {
1407		/// Combines two `Option` values with a by-reference binary function.
1408		#[document_signature]
1409		#[document_type_parameters(
1410			"The lifetime.",
1411			"First input type.",
1412			"Second input type.",
1413			"Output type."
1414		)]
1415		#[document_parameters("The binary function.", "The first option.", "The second option.")]
1416		#[document_returns("The combined result, or `None` if either input is `None`.")]
1417		#[document_examples]
1418		///
1419		/// ```
1420		/// use fp_library::{
1421		/// 	brands::*,
1422		/// 	functions::*,
1423		/// };
1424		///
1425		/// let result = explicit::lift2::<OptionBrand, _, _, _, _, _, _>(
1426		/// 	|a: &i32, b: &i32| *a + *b,
1427		/// 	&Some(1),
1428		/// 	&Some(2),
1429		/// );
1430		/// assert_eq!(result, Some(3));
1431		/// ```
1432		fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
1433			func: impl Fn(&A, &B) -> C + 'a,
1434			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1435			fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1436		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1437			match (fa.as_ref(), fb.as_ref()) {
1438				(Some(a), Some(b)) => Some(func(a, b)),
1439				_ => None,
1440			}
1441		}
1442	}
1443
1444	impl RefSemiapplicative for OptionBrand {
1445		/// Applies a wrapped by-ref function to an `Option` value.
1446		#[document_signature]
1447		#[document_type_parameters(
1448			"The lifetime.",
1449			"The function brand.",
1450			"The input type.",
1451			"The output type."
1452		)]
1453		#[document_parameters(
1454			"The option containing the by-ref function.",
1455			"The option containing the value."
1456		)]
1457		#[document_returns("The result of applying the function, or `None`.")]
1458		#[document_examples]
1459		///
1460		/// ```
1461		/// use fp_library::{
1462		/// 	brands::*,
1463		/// 	classes::*,
1464		/// 	functions::*,
1465		/// };
1466		///
1467		/// let f: std::rc::Rc<dyn Fn(&i32) -> i32> = std::rc::Rc::new(|x: &i32| *x + 1);
1468		/// let result = ref_apply::<RcFnBrand, OptionBrand, _, _>(&Some(f), &Some(5));
1469		/// assert_eq!(result, Some(6));
1470		/// ```
1471		fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
1472			ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
1473			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1474		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1475			match (ff, fa.as_ref()) {
1476				(Some(f), Some(a)) => Some((**f)(a)),
1477				_ => None,
1478			}
1479		}
1480	}
1481
1482	impl RefSemimonad for OptionBrand {
1483		/// Chains `Option` computations by reference.
1484		#[document_signature]
1485		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1486		#[document_parameters("The input option.", "The function to apply by reference.")]
1487		#[document_returns("The result of applying the function, or `None`.")]
1488		#[document_examples]
1489		///
1490		/// ```
1491		/// use fp_library::{
1492		/// 	brands::*,
1493		/// 	functions::*,
1494		/// };
1495		///
1496		/// let result: Option<String> =
1497		/// 	explicit::bind::<OptionBrand, _, _, _, _>(&Some(42), |x: &i32| Some(x.to_string()));
1498		/// assert_eq!(result, Some("42".to_string()));
1499		/// ```
1500		fn ref_bind<'a, A: 'a, B: 'a>(
1501			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1502			f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1503		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1504			fa.as_ref().and_then(f)
1505		}
1506	}
1507}
1508
1509#[cfg(test)]
1510mod tests {
1511
1512	use {
1513		crate::{
1514			brands::*,
1515			classes::*,
1516			functions::*,
1517		},
1518		quickcheck_macros::quickcheck,
1519	};
1520
1521	// Functor Laws
1522
1523	/// Tests the identity law for Functor.
1524	#[quickcheck]
1525	fn functor_identity(x: Option<i32>) -> bool {
1526		explicit::map::<OptionBrand, _, _, _, _>(identity, x) == x
1527	}
1528
1529	/// Tests the composition law for Functor.
1530	#[quickcheck]
1531	fn functor_composition(x: Option<i32>) -> bool {
1532		let f = |x: i32| x.wrapping_add(1);
1533		let g = |x: i32| x.wrapping_mul(2);
1534		explicit::map::<OptionBrand, _, _, _, _>(compose(f, g), x)
1535			== explicit::map::<OptionBrand, _, _, _, _>(
1536				f,
1537				explicit::map::<OptionBrand, _, _, _, _>(g, x),
1538			)
1539	}
1540
1541	// Applicative Laws
1542
1543	/// Tests the identity law for Applicative.
1544	#[quickcheck]
1545	fn applicative_identity(v: Option<i32>) -> bool {
1546		apply(pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(identity)), v) == v
1547	}
1548
1549	/// Tests the homomorphism law for Applicative.
1550	#[quickcheck]
1551	fn applicative_homomorphism(x: i32) -> bool {
1552		let f = |x: i32| x.wrapping_mul(2);
1553		apply(pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(f)), pure::<OptionBrand, _>(x))
1554			== pure::<OptionBrand, _>(f(x))
1555	}
1556
1557	/// Tests the composition law for Applicative.
1558	#[quickcheck]
1559	fn applicative_composition(
1560		w: Option<i32>,
1561		u_is_some: bool,
1562		v_is_some: bool,
1563	) -> bool {
1564		let v_fn = |x: i32| x.wrapping_mul(2);
1565		let u_fn = |x: i32| x.wrapping_add(1);
1566
1567		let v =
1568			if v_is_some { pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(v_fn)) } else { None };
1569		let u =
1570			if u_is_some { pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(u_fn)) } else { None };
1571
1572		// RHS: u <*> (v <*> w)
1573		let vw = apply(v.clone(), w);
1574		let rhs = apply(u.clone(), vw);
1575
1576		// LHS: pure(compose) <*> u <*> v <*> w
1577		// equivalent to (u . v) <*> w
1578		let uv = match (u, v) {
1579			(Some(uf), Some(vf)) => {
1580				let composed = move |x| uf(vf(x));
1581				Some(<RcFnBrand as LiftFn>::new(composed))
1582			}
1583			_ => None,
1584		};
1585
1586		let lhs = apply(uv, w);
1587
1588		lhs == rhs
1589	}
1590
1591	/// Tests the interchange law for Applicative.
1592	#[quickcheck]
1593	fn applicative_interchange(y: i32) -> bool {
1594		// u <*> pure y = pure ($ y) <*> u
1595		let f = |x: i32| x.wrapping_mul(2);
1596		let u = pure::<OptionBrand, _>(<RcFnBrand as LiftFn>::new(f));
1597
1598		let lhs = apply(u.clone(), pure::<OptionBrand, _>(y));
1599
1600		let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1601		let rhs = apply(pure::<OptionBrand, _>(rhs_fn), u);
1602
1603		lhs == rhs
1604	}
1605
1606	// Monad Laws
1607
1608	/// Tests the left identity law for Monad.
1609	#[quickcheck]
1610	fn monad_left_identity(a: i32) -> bool {
1611		let f = |x: i32| Some(x.wrapping_mul(2));
1612		explicit::bind::<OptionBrand, _, _, _, _>(pure::<OptionBrand, _>(a), f) == f(a)
1613	}
1614
1615	/// Tests the right identity law for Monad.
1616	#[quickcheck]
1617	fn monad_right_identity(m: Option<i32>) -> bool {
1618		explicit::bind::<OptionBrand, _, _, _, _>(m, pure::<OptionBrand, _>) == m
1619	}
1620
1621	/// Tests the associativity law for Monad.
1622	#[quickcheck]
1623	fn monad_associativity(m: Option<i32>) -> bool {
1624		let f = |x: i32| Some(x.wrapping_mul(2));
1625		let g = |x: i32| Some(x.wrapping_add(1));
1626		explicit::bind::<OptionBrand, _, _, _, _>(
1627			explicit::bind::<OptionBrand, _, _, _, _>(m, f),
1628			g,
1629		) == explicit::bind::<OptionBrand, _, _, _, _>(m, |x| {
1630			explicit::bind::<OptionBrand, _, _, _, _>(f(x), g)
1631		})
1632	}
1633
1634	// Edge Cases
1635
1636	/// Tests `map` on `None`.
1637	#[test]
1638	fn map_none() {
1639		assert_eq!(explicit::map::<OptionBrand, _, _, _, _>(|x: i32| x + 1, None), None);
1640	}
1641
1642	/// Tests `bind` on `None`.
1643	#[test]
1644	fn bind_none() {
1645		assert_eq!(explicit::bind::<OptionBrand, _, _, _, _>(None, |x: i32| Some(x + 1)), None);
1646	}
1647
1648	/// Tests `bind` returning `None`.
1649	#[test]
1650	fn bind_returning_none() {
1651		assert_eq!(explicit::bind::<OptionBrand, _, _, _, _>(Some(5), |_| None::<i32>), None);
1652	}
1653
1654	/// Tests `fold_right` on `None`.
1655	#[test]
1656	fn fold_right_none() {
1657		assert_eq!(
1658			crate::functions::explicit::fold_right::<RcFnBrand, OptionBrand, _, _, _, _>(
1659				|x: i32, acc| x + acc,
1660				0,
1661				None
1662			),
1663			0
1664		);
1665	}
1666
1667	/// Tests `fold_left` on `None`.
1668	#[test]
1669	fn fold_left_none() {
1670		assert_eq!(
1671			crate::functions::explicit::fold_left::<RcFnBrand, OptionBrand, _, _, _, _>(
1672				|acc, x: i32| acc + x,
1673				0,
1674				None
1675			),
1676			0
1677		);
1678	}
1679
1680	/// Tests `traverse` on `None`.
1681	#[test]
1682	fn traverse_none() {
1683		assert_eq!(
1684			crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1685				|x: i32| Some(x + 1),
1686				None
1687			),
1688			Some(None)
1689		);
1690	}
1691
1692	/// Tests `traverse` returning `None`.
1693	#[test]
1694	fn traverse_returning_none() {
1695		assert_eq!(
1696			crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1697				|_: i32| None::<i32>,
1698				Some(5)
1699			),
1700			None
1701		);
1702	}
1703
1704	// MonadRec tests
1705
1706	/// Tests the MonadRec identity law: `tail_rec_m(|a| pure(Done(a)), x) == pure(x)`.
1707	#[quickcheck]
1708	fn monad_rec_identity(x: i32) -> bool {
1709		use {
1710			crate::classes::monad_rec::tail_rec_m,
1711			core::ops::ControlFlow,
1712		};
1713		tail_rec_m::<OptionBrand, _, _>(|a| Some(ControlFlow::Break(a)), x) == Some(x)
1714	}
1715
1716	/// Tests a recursive computation that sums a range via `tail_rec_m`.
1717	#[test]
1718	fn monad_rec_sum_range() {
1719		use {
1720			crate::classes::monad_rec::tail_rec_m,
1721			core::ops::ControlFlow,
1722		};
1723		// Sum 1..=100 using tail_rec_m
1724		let result = tail_rec_m::<OptionBrand, _, _>(
1725			|(n, acc)| {
1726				if n == 0 {
1727					Some(ControlFlow::Break(acc))
1728				} else {
1729					Some(ControlFlow::Continue((n - 1, acc + n)))
1730				}
1731			},
1732			(100i64, 0i64),
1733		);
1734		assert_eq!(result, Some(5050));
1735	}
1736
1737	/// Tests that `tail_rec_m` short-circuits on `None`.
1738	#[test]
1739	fn monad_rec_short_circuit() {
1740		use {
1741			crate::classes::monad_rec::tail_rec_m,
1742			core::ops::ControlFlow,
1743		};
1744		let result: Option<i32> = tail_rec_m::<OptionBrand, _, _>(
1745			|n| {
1746				if n == 5 { None } else { Some(ControlFlow::Continue(n + 1)) }
1747			},
1748			0,
1749		);
1750		assert_eq!(result, None);
1751	}
1752
1753	/// Tests stack safety: `tail_rec_m` handles large iteration counts.
1754	#[test]
1755	fn monad_rec_stack_safety() {
1756		use {
1757			crate::classes::monad_rec::tail_rec_m,
1758			core::ops::ControlFlow,
1759		};
1760		let iterations: i64 = 200_000;
1761		let result = tail_rec_m::<OptionBrand, _, _>(
1762			|acc| {
1763				if acc < iterations {
1764					Some(ControlFlow::Continue(acc + 1))
1765				} else {
1766					Some(ControlFlow::Break(acc))
1767				}
1768			},
1769			0i64,
1770		);
1771		assert_eq!(result, Some(iterations));
1772	}
1773
1774	// RefFunctor Laws
1775
1776	/// Tests the identity law for RefFunctor: `ref_map(|x| *x, opt) == opt`.
1777	#[quickcheck]
1778	fn ref_functor_identity(opt: Option<i32>) -> bool {
1779		use crate::classes::ref_functor::RefFunctor;
1780		OptionBrand::ref_map(|x: &i32| *x, &opt) == opt
1781	}
1782
1783	/// Tests the composition law for RefFunctor.
1784	#[quickcheck]
1785	fn ref_functor_composition(opt: Option<i32>) -> bool {
1786		use crate::classes::ref_functor::RefFunctor;
1787		let f = |x: &i32| x.wrapping_add(1);
1788		let g = |x: &i32| x.wrapping_mul(2);
1789		OptionBrand::ref_map(|x: &i32| f(&g(x)), &opt)
1790			== OptionBrand::ref_map(f, &OptionBrand::ref_map(g, &opt))
1791	}
1792
1793	// RefSemimonad Laws
1794
1795	/// Tests the left identity law for RefSemimonad: `ref_bind(Some(x), |a| Some(*a)) == Some(x)`.
1796	#[quickcheck]
1797	fn ref_semimonad_left_identity(x: i32) -> bool {
1798		use crate::classes::ref_semimonad::RefSemimonad;
1799		OptionBrand::ref_bind(&Some(x), |a: &i32| Some(*a)) == Some(x)
1800	}
1801
1802	// RefFoldable Laws
1803
1804	/// Tests RefFoldable fold_map on Option with Additive monoid.
1805	#[quickcheck]
1806	fn ref_foldable_fold_map(opt: Option<i32>) -> bool {
1807		use crate::{
1808			classes::ref_foldable::RefFoldable,
1809			types::Additive,
1810		};
1811		let result = OptionBrand::ref_fold_map::<RcFnBrand, _, _>(|x: &i32| Additive(*x), &opt);
1812		let expected = match opt {
1813			Some(v) => Additive(v),
1814			None => Additive(0),
1815		};
1816		result == expected
1817	}
1818
1819	// RefSemimonad Laws (continued)
1820
1821	/// Tests the right identity law for RefSemimonad:
1822	/// `ref_bind(m, |a| ref_pure(a)) == m`.
1823	#[quickcheck]
1824	fn ref_semimonad_right_identity(opt: Option<i32>) -> bool {
1825		use crate::classes::{
1826			ref_pointed::RefPointed,
1827			ref_semimonad::RefSemimonad,
1828		};
1829		OptionBrand::ref_bind(&opt, |a: &i32| OptionBrand::ref_pure(a)) == opt
1830	}
1831
1832	/// Tests the associativity law for RefSemimonad.
1833	#[quickcheck]
1834	fn ref_semimonad_associativity(opt: Option<i32>) -> bool {
1835		use crate::classes::ref_semimonad::RefSemimonad;
1836		let f = |a: &i32| if *a > 0 { Some(a.wrapping_mul(2)) } else { None };
1837		let g = |b: &i32| Some(b.wrapping_add(10));
1838		let lhs = OptionBrand::ref_bind(&OptionBrand::ref_bind(&opt, f), g);
1839		let rhs = OptionBrand::ref_bind(&opt, |a: &i32| OptionBrand::ref_bind(&f(a), g));
1840		lhs == rhs
1841	}
1842
1843	// RefLift Laws
1844
1845	/// Tests the identity law for RefLift:
1846	/// `ref_lift2(|_, b| *b, pure(unit), fa) == fa`.
1847	#[quickcheck]
1848	fn ref_lift_identity(opt: Option<i32>) -> bool {
1849		use crate::classes::ref_lift::RefLift;
1850		OptionBrand::ref_lift2(|_: &(), b: &i32| *b, &Some(()), &opt) == opt
1851	}
1852
1853	/// Tests commutativity of ref_lift2 (for Option specifically):
1854	/// `ref_lift2(f, a, b) == ref_lift2(|b, a| f(a, b), b, a)`.
1855	#[quickcheck]
1856	fn ref_lift2_commutativity(
1857		a: Option<i32>,
1858		b: Option<i32>,
1859	) -> bool {
1860		use crate::classes::ref_lift::RefLift;
1861		let lhs = OptionBrand::ref_lift2(|x: &i32, y: &i32| x.wrapping_add(*y), &a, &b);
1862		let rhs = OptionBrand::ref_lift2(|y: &i32, x: &i32| x.wrapping_add(*y), &b, &a);
1863		lhs == rhs
1864	}
1865
1866	// RefTraversable Laws
1867
1868	/// Tests the identity law for RefTraversable:
1869	/// `ref_traverse(|a| Identity(*a), ta) == Identity(ta)`.
1870	#[quickcheck]
1871	fn ref_traversable_identity(opt: Option<i32>) -> bool {
1872		use crate::{
1873			classes::ref_traversable::RefTraversable,
1874			types::Identity,
1875		};
1876		let result: Identity<Option<i32>> =
1877			OptionBrand::ref_traverse::<RcFnBrand, _, _, IdentityBrand>(
1878				|a: &i32| Identity(*a),
1879				&opt,
1880			);
1881		result == Identity(opt)
1882	}
1883
1884	/// Tests RefTraversable naturality: ref_traverse(f, ta) produces
1885	/// the same result as traverse(|a| f(&a), ta).
1886	#[quickcheck]
1887	fn ref_traversable_consistent_with_traverse(opt: Option<i32>) -> bool {
1888		use crate::classes::{
1889			ref_traversable::RefTraversable,
1890			traversable::Traversable,
1891		};
1892		let ref_result: Option<Option<String>> =
1893			OptionBrand::ref_traverse::<RcFnBrand, _, _, OptionBrand>(
1894				|a: &i32| Some(a.to_string()),
1895				&opt,
1896			);
1897		let val_result: Option<Option<String>> =
1898			OptionBrand::traverse::<i32, String, OptionBrand>(|a: i32| Some(a.to_string()), opt);
1899		ref_result == val_result
1900	}
1901
1902	// RefCompactable Laws
1903
1904	/// RefCompactable identity: ref_compact(ref_map(Some, &fa)) == fa.clone()
1905	#[quickcheck]
1906	fn ref_compactable_identity(x: Option<i32>) -> bool {
1907		use crate::classes::ref_compactable::ref_compact;
1908		let mapped: Option<Option<i32>> = x.as_ref().map(|a| Some(*a));
1909		ref_compact::<OptionBrand, _>(&mapped) == x
1910	}
1911
1912	// RefAlt Laws
1913
1914	/// RefAlt associativity
1915	#[quickcheck]
1916	fn ref_alt_associativity(
1917		x: Option<i32>,
1918		y: Option<i32>,
1919		z: Option<i32>,
1920	) -> bool {
1921		use crate::classes::ref_alt::ref_alt;
1922		ref_alt::<OptionBrand, _>(&ref_alt::<OptionBrand, _>(&x, &y), &z)
1923			== ref_alt::<OptionBrand, _>(&x, &ref_alt::<OptionBrand, _>(&y, &z))
1924	}
1925}