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.
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::OptionBrand,
11			classes::{
12				Applicative,
13				ApplyFirst,
14				ApplySecond,
15				CloneableFn,
16				Compactable,
17				Filterable,
18				Foldable,
19				Functor,
20				Lift,
21				Monoid,
22				ParFoldable,
23				Pointed,
24				Semiapplicative,
25				Semimonad,
26				SendCloneableFn,
27				Traversable,
28				Witherable,
29				foldable_with_index::FoldableWithIndex,
30				functor_with_index::FunctorWithIndex,
31				traversable_with_index::TraversableWithIndex,
32			},
33			impl_kind,
34			kinds::*,
35		},
36		fp_macros::*,
37	};
38
39	impl_kind! {
40		for OptionBrand {
41			type Of<'a, A: 'a>: 'a = Option<A>;
42		}
43	}
44
45	impl Functor for OptionBrand {
46		/// Maps a function over the value in the option.
47		///
48		/// 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`.
49		#[document_signature]
50		///
51		#[document_type_parameters(
52			"The lifetime of the value.",
53			"The type of the value inside the option.",
54			"The type of the result of applying the function."
55		)]
56		///
57		#[document_parameters("The function to apply to the value.", "The option to map over.")]
58		///
59		#[document_returns(
60			"A new option containing the result of applying the function, or `None`."
61		)]
62		///
63		#[document_examples]
64		///
65		/// ```
66		/// use fp_library::{
67		/// 	brands::*,
68		/// 	functions::*,
69		/// };
70		///
71		/// let x = Some(5);
72		/// let y = map::<OptionBrand, _, _>(|i| i * 2, x);
73		/// assert_eq!(y, Some(10));
74		/// ```
75		fn map<'a, A: 'a, B: 'a>(
76			func: impl Fn(A) -> B + 'a,
77			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
78		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
79			fa.map(func)
80		}
81	}
82
83	impl Lift for OptionBrand {
84		/// Lifts a binary function into the option context.
85		///
86		/// This method lifts a binary function to operate on values within the option context.
87		#[document_signature]
88		///
89		#[document_type_parameters(
90			"The lifetime of the values.",
91			"The type of the first option's value.",
92			"The type of the second option's value.",
93			"The return type of the function."
94		)]
95		///
96		#[document_parameters(
97			"The binary function to apply.",
98			"The first option.",
99			"The second option."
100		)]
101		///
102		#[document_returns("`Some(f(a, b))` if both options are `Some`, otherwise `None`.")]
103		#[document_examples]
104		///
105		/// ```
106		/// use fp_library::{
107		/// 	brands::*,
108		/// 	functions::*,
109		/// };
110		///
111		/// let x = Some(1);
112		/// let y = Some(2);
113		/// let z = lift2::<OptionBrand, _, _, _>(|a, b| a + b, x, y);
114		/// assert_eq!(z, Some(3));
115		/// ```
116		fn lift2<'a, A, B, C>(
117			func: impl Fn(A, B) -> C + 'a,
118			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
119			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
120		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
121		where
122			A: 'a,
123			B: 'a,
124			C: 'a, {
125			fa.zip(fb).map(|(a, b)| func(a, b))
126		}
127	}
128
129	impl Pointed for OptionBrand {
130		/// Wraps a value in an option.
131		///
132		/// This method wraps a value in an option context.
133		#[document_signature]
134		///
135		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
136		///
137		#[document_parameters("The value to wrap.")]
138		///
139		#[document_returns("`Some(a)`.")]
140		///
141		#[document_examples]
142		///
143		/// ```
144		/// use fp_library::{
145		/// 	brands::OptionBrand,
146		/// 	functions::*,
147		/// };
148		///
149		/// let x = pure::<OptionBrand, _>(5);
150		/// assert_eq!(x, Some(5));
151		/// ```
152		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
153			Some(a)
154		}
155	}
156
157	impl ApplyFirst for OptionBrand {}
158	impl ApplySecond for OptionBrand {}
159
160	impl Semiapplicative for OptionBrand {
161		/// Applies a wrapped function to a wrapped value.
162		///
163		/// This method applies a function wrapped in an option to a value wrapped in an option.
164		#[document_signature]
165		///
166		#[document_type_parameters(
167			"The lifetime of the values.",
168			"The brand of the cloneable function wrapper.",
169			"The type of the input value.",
170			"The type of the output value."
171		)]
172		///
173		#[document_parameters(
174			"The option containing the function.",
175			"The option containing the value."
176		)]
177		///
178		#[document_returns("`Some(f(a))` if both are `Some`, otherwise `None`.")]
179		#[document_examples]
180		///
181		/// ```
182		/// use fp_library::{
183		/// 	brands::*,
184		/// 	classes::*,
185		/// 	functions::*,
186		/// };
187		///
188		/// let f = Some(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
189		/// let x = Some(5);
190		/// let y = apply::<RcFnBrand, OptionBrand, _, _>(f, x);
191		/// assert_eq!(y, Some(10));
192		/// ```
193		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
194			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
195			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
196		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
197			match (ff, fa) {
198				(Some(f), Some(a)) => Some(f(a)),
199				_ => None,
200			}
201		}
202	}
203
204	impl Semimonad for OptionBrand {
205		/// Chains option computations.
206		///
207		/// This method chains two option computations, where the second computation depends on the result of the first.
208		#[document_signature]
209		///
210		#[document_type_parameters(
211			"The lifetime of the values.",
212			"The type of the result of the first computation.",
213			"The type of the result of the second computation."
214		)]
215		///
216		#[document_parameters(
217			"The first option.",
218			"The function to apply to the value inside the option."
219		)]
220		///
221		#[document_returns(
222			"The result of applying `f` to the value if `ma` is `Some`, otherwise `None`."
223		)]
224		#[document_examples]
225		///
226		/// ```
227		/// use fp_library::{
228		/// 	brands::OptionBrand,
229		/// 	functions::*,
230		/// };
231		///
232		/// let x = Some(5);
233		/// let y = bind::<OptionBrand, _, _>(x, |i| Some(i * 2));
234		/// assert_eq!(y, Some(10));
235		/// ```
236		fn bind<'a, A: 'a, B: 'a>(
237			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
238			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
239		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
240			ma.and_then(func)
241		}
242	}
243
244	impl Foldable for OptionBrand {
245		/// Folds the option from the right.
246		///
247		/// 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.
248		#[document_signature]
249		///
250		#[document_type_parameters(
251			"The lifetime of the values.",
252			"The brand of the cloneable function to use.",
253			"The type of the elements in the structure.",
254			"The type of the accumulator."
255		)]
256		///
257		#[document_parameters("The folding function.", "The initial value.", "The option to fold.")]
258		///
259		#[document_returns("`func(a, initial)` if `fa` is `Some(a)`, otherwise `initial`.")]
260		///
261		#[document_examples]
262		///
263		/// ```
264		/// use fp_library::{
265		/// 	brands::*,
266		/// 	functions::*,
267		/// };
268		///
269		/// let x = Some(5);
270		/// let y = fold_right::<RcFnBrand, OptionBrand, _, _>(|a, b| a + b, 10, x);
271		/// assert_eq!(y, 15);
272		/// ```
273		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
274			func: impl Fn(A, B) -> B + 'a,
275			initial: B,
276			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
277		) -> B
278		where
279			FnBrand: CloneableFn + 'a, {
280			match fa {
281				Some(a) => func(a, initial),
282				None => initial,
283			}
284		}
285
286		/// Folds the option from the left.
287		///
288		/// 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.
289		#[document_signature]
290		///
291		#[document_type_parameters(
292			"The lifetime of the values.",
293			"The brand of the cloneable function to use.",
294			"The type of the elements in the structure.",
295			"The type of the accumulator."
296		)]
297		///
298		#[document_parameters(
299			"The function to apply to the accumulator and each element.",
300			"The initial value of the accumulator.",
301			"The option to fold."
302		)]
303		///
304		#[document_returns("`f(initial, a)` if `fa` is `Some(a)`, otherwise `initial`.")]
305		#[document_examples]
306		///
307		/// ```
308		/// use fp_library::{
309		/// 	brands::*,
310		/// 	functions::*,
311		/// };
312		///
313		/// let x = Some(5);
314		/// let y = fold_left::<RcFnBrand, OptionBrand, _, _>(|b, a| b + a, 10, x);
315		/// assert_eq!(y, 15);
316		/// ```
317		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
318			func: impl Fn(B, A) -> B + 'a,
319			initial: B,
320			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
321		) -> B
322		where
323			FnBrand: CloneableFn + 'a, {
324			match fa {
325				Some(a) => func(initial, a),
326				None => initial,
327			}
328		}
329
330		/// Maps the value to a monoid and returns it, or returns empty.
331		///
332		/// This method maps the element of the option to a monoid. If the option is `None`, it returns the monoid's identity element.
333		#[document_signature]
334		///
335		#[document_type_parameters(
336			"The lifetime of the values.",
337			"The brand of the cloneable function to use.",
338			"The type of the elements in the structure.",
339			"The type of the monoid."
340		)]
341		///
342		#[document_parameters("The mapping function.", "The option to fold.")]
343		///
344		#[document_returns("`func(a)` if `fa` is `Some(a)`, otherwise `M::empty()`.")]
345		///
346		#[document_examples]
347		///
348		/// ```
349		/// use fp_library::{
350		/// 	brands::*,
351		/// 	functions::*,
352		/// };
353		///
354		/// let x = Some(5);
355		/// let y = fold_map::<RcFnBrand, OptionBrand, _, _>(|a: i32| a.to_string(), x);
356		/// assert_eq!(y, "5".to_string());
357		/// ```
358		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
359			func: impl Fn(A) -> M + 'a,
360			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
361		) -> M
362		where
363			M: Monoid + 'a,
364			FnBrand: CloneableFn + 'a, {
365			match fa {
366				Some(a) => func(a),
367				None => M::empty(),
368			}
369		}
370	}
371
372	impl Traversable for OptionBrand {
373		/// Traverses the option with an applicative function.
374		///
375		/// 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)`.
376		#[document_signature]
377		///
378		#[document_type_parameters(
379			"The lifetime of the values.",
380			"The type of the elements in the traversable structure.",
381			"The type of the elements in the resulting traversable structure.",
382			"The applicative context."
383		)]
384		///
385		#[document_parameters(
386			"The function to apply to each element, returning a value in an applicative context.",
387			"The option to traverse."
388		)]
389		///
390		#[document_returns("The option wrapped in the applicative context.")]
391		#[document_examples]
392		///
393		/// ```
394		/// use fp_library::{
395		/// 	brands::OptionBrand,
396		/// 	functions::*,
397		/// };
398		///
399		/// let x = Some(5);
400		/// let y = traverse::<OptionBrand, _, _, OptionBrand>(|a| Some(a * 2), x);
401		/// assert_eq!(y, Some(Some(10)));
402		/// ```
403		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
404			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
405			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
406		) -> 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>)>)
407		where
408			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
409			match ta {
410				Some(a) => F::map(|b| Some(b), func(a)),
411				None => F::pure(None),
412			}
413		}
414
415		/// Sequences an option of applicative.
416		///
417		/// This method evaluates the computation inside the option and wraps the result in the applicative context. If `None`, it returns `pure(None)`.
418		#[document_signature]
419		///
420		#[document_type_parameters(
421			"The lifetime of the values.",
422			"The type of the elements in the traversable structure.",
423			"The applicative context."
424		)]
425		///
426		#[document_parameters("The option containing the applicative value.")]
427		///
428		#[document_returns("The result of the traversal.")]
429		///
430		/// # Returns
431		///
432		/// The option wrapped in the applicative context.
433		#[document_examples]
434		///
435		/// ```
436		/// use fp_library::{
437		/// 	brands::OptionBrand,
438		/// 	functions::*,
439		/// };
440		///
441		/// let x = Some(Some(5));
442		/// let y = sequence::<OptionBrand, _, OptionBrand>(x);
443		/// assert_eq!(y, Some(Some(5)));
444		/// ```
445		fn sequence<'a, A: 'a + Clone, F: Applicative>(
446			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>)>)
447		) -> 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>)>)
448		where
449			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
450			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
451			match ta {
452				Some(fa) => F::map(|a| Some(a), fa),
453				None => F::pure(None),
454			}
455		}
456	}
457
458	impl FunctorWithIndex<()> for OptionBrand {
459		/// Maps a function over the value in the option, providing the index `()`.
460		#[document_signature]
461		#[document_type_parameters(
462			"The lifetime of the value.",
463			"The type of the value inside the option.",
464			"The type of the result of applying the function."
465		)]
466		#[document_parameters(
467			"The function to apply to the value and its index.",
468			"The option to map over."
469		)]
470		#[document_returns(
471			"A new option containing the result of applying the function, or `None`."
472		)]
473		#[document_examples]
474		///
475		/// ```
476		/// use fp_library::{
477		/// 	brands::OptionBrand,
478		/// 	classes::functor_with_index::FunctorWithIndex,
479		/// 	functions::*,
480		/// };
481		/// let x = Some(5);
482		/// let y = <OptionBrand as FunctorWithIndex<()>>::map_with_index(|_, i| i * 2, x);
483		/// assert_eq!(y, Some(10));
484		/// ```
485		fn map_with_index<'a, A: 'a, B: 'a>(
486			f: impl Fn((), A) -> B + 'a,
487			fa: Option<A>,
488		) -> Option<B> {
489			fa.map(|a| f((), a))
490		}
491	}
492
493	impl FoldableWithIndex<()> for OptionBrand {
494		/// Folds the option using a monoid, providing the index `()`.
495		#[document_signature]
496		#[document_type_parameters(
497			"The lifetime of the value.",
498			"The type of the value inside the option.",
499			"The monoid type."
500		)]
501		#[document_parameters(
502			"The function to apply to the value and its index.",
503			"The option to fold."
504		)]
505		#[document_returns("The monoid value.")]
506		#[document_examples]
507		///
508		/// ```
509		/// use fp_library::{
510		/// 	brands::OptionBrand,
511		/// 	classes::foldable_with_index::FoldableWithIndex,
512		/// 	functions::*,
513		/// };
514		/// let x = Some(5);
515		/// let y =
516		/// 	<OptionBrand as FoldableWithIndex<()>>::fold_map_with_index(|_, i: i32| i.to_string(), x);
517		/// assert_eq!(y, "5".to_string());
518		/// ```
519		fn fold_map_with_index<'a, A: 'a, R: Monoid>(
520			f: impl Fn((), A) -> R + 'a,
521			fa: Option<A>,
522		) -> R {
523			match fa {
524				Some(a) => f((), a),
525				None => R::empty(),
526			}
527		}
528	}
529
530	impl TraversableWithIndex<()> for OptionBrand {
531		/// Traverses the option with an applicative function, providing the index `()`.
532		#[document_signature]
533		#[document_type_parameters(
534			"The lifetime of the value.",
535			"The type of the value inside the option.",
536			"The type of the result.",
537			"The applicative context."
538		)]
539		#[document_parameters(
540			"The function to apply to the value and its index, returning a value in an applicative context.",
541			"The option to traverse."
542		)]
543		#[document_returns("The option wrapped in the applicative context.")]
544		#[document_examples]
545		///
546		/// ```
547		/// use fp_library::{
548		/// 	brands::OptionBrand,
549		/// 	classes::traversable_with_index::TraversableWithIndex,
550		/// 	functions::*,
551		/// };
552		/// let x = Some(5);
553		/// let y = <OptionBrand as TraversableWithIndex<()>>::traverse_with_index::<i32, i32, OptionBrand>(
554		/// 	|_, i| Some(i * 2),
555		/// 	x,
556		/// );
557		/// assert_eq!(y, Some(Some(10)));
558		/// ```
559		fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
560			f: impl Fn((), A) -> M::Of<'a, B> + 'a,
561			ta: Option<A>,
562		) -> M::Of<'a, Option<B>> {
563			match ta {
564				Some(a) => M::map(|b| Some(b), f((), a)),
565				None => M::pure(None),
566			}
567		}
568	}
569
570	impl ParFoldable for OptionBrand {
571		/// Maps the value to a monoid and returns it, or returns empty, in parallel.
572		///
573		/// This method maps the element of the option to a monoid. Since `Option` contains at most one element, no actual parallelism occurs, but the interface is satisfied.
574		#[document_signature]
575		///
576		#[document_type_parameters(
577			"The lifetime of the values.",
578			"The brand of the cloneable function wrapper.",
579			"The element type.",
580			"The monoid type."
581		)]
582		///
583		#[document_parameters("The mapping function.", "The option to fold.")]
584		///
585		#[document_returns("The combined monoid value.")]
586		///
587		#[document_examples]
588		///
589		/// ```
590		/// use fp_library::{
591		/// 	brands::*,
592		/// 	functions::*,
593		/// };
594		///
595		/// let x = Some(1);
596		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
597		/// let y = par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x);
598		/// assert_eq!(y, "1".to_string());
599		/// ```
600		fn par_fold_map<'a, FnBrand, A, M>(
601			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
602			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
603		) -> M
604		where
605			FnBrand: 'a + SendCloneableFn,
606			A: 'a + Clone + Send + Sync,
607			M: Monoid + Send + Sync + 'a, {
608			match fa {
609				Some(a) => func(a),
610				None => M::empty(),
611			}
612		}
613	}
614
615	impl Compactable for OptionBrand {
616		/// Compacts a nested option.
617		///
618		/// This method flattens a nested option.
619		#[document_signature]
620		///
621		#[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
622		///
623		#[document_parameters("The nested option.")]
624		///
625		#[document_returns("The flattened option.")]
626		///
627		#[document_examples]
628		///
629		/// ```
630		/// use fp_library::{
631		/// 	brands::OptionBrand,
632		/// 	functions::*,
633		/// };
634		///
635		/// let x = Some(Some(5));
636		/// let y = compact::<OptionBrand, _>(x);
637		/// assert_eq!(y, Some(5));
638		/// ```
639		fn compact<'a, A: 'a>(
640			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
641			'a,
642			Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
643		>)
644		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
645			fa.flatten()
646		}
647
648		/// Separates an option of result.
649		///
650		/// This method separates an option of result into a pair of options.
651		#[document_signature]
652		///
653		#[document_type_parameters(
654			"The lifetime of the values.",
655			"The type of the error value.",
656			"The type of the success value."
657		)]
658		///
659		#[document_parameters("The option of result.")]
660		///
661		#[document_returns("A pair of options.")]
662		///
663		#[document_examples]
664		///
665		/// ```
666		/// use fp_library::{
667		/// 	brands::*,
668		/// 	functions::*,
669		/// };
670		///
671		/// let x: Option<Result<i32, &str>> = Some(Ok(5));
672		/// let (errs, oks) = separate::<OptionBrand, _, _>(x);
673		/// assert_eq!(oks, Some(5));
674		/// assert_eq!(errs, None);
675		/// ```
676		fn separate<'a, E: 'a, O: 'a>(
677			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
678		) -> (
679			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
680			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
681		) {
682			match fa {
683				Some(Ok(o)) => (None, Some(o)),
684				Some(Err(e)) => (Some(e), None),
685				None => (None, None),
686			}
687		}
688	}
689
690	impl Filterable for OptionBrand {
691		/// Partitions an option based on a function that returns a result.
692		///
693		/// This method partitions an option based on a function that returns a result.
694		#[document_signature]
695		///
696		#[document_type_parameters(
697			"The lifetime of the values.",
698			"The type of the input value.",
699			"The type of the error value.",
700			"The type of the success value."
701		)]
702		///
703		#[document_parameters("The function to apply.", "The option to partition.")]
704		///
705		#[document_returns("A pair of options.")]
706		///
707		#[document_examples]
708		///
709		/// ```
710		/// use fp_library::{
711		/// 	brands::*,
712		/// 	functions::*,
713		/// };
714		///
715		/// let x = Some(5);
716		/// let (errs, oks) =
717		/// 	partition_map::<OptionBrand, _, _, _>(|a| if a > 2 { Ok(a) } else { Err(a) }, x);
718		/// assert_eq!(oks, Some(5));
719		/// assert_eq!(errs, None);
720		/// ```
721		fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
722			func: impl Fn(A) -> Result<O, E> + 'a,
723			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
724		) -> (
725			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
726			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
727		) {
728			match fa {
729				Some(a) => match func(a) {
730					Ok(o) => (None, Some(o)),
731					Err(e) => (Some(e), None),
732				},
733				None => (None, None),
734			}
735		}
736
737		/// Partitions an option based on a predicate.
738		///
739		/// This method partitions an option based on a predicate.
740		#[document_signature]
741		///
742		#[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
743		///
744		#[document_parameters("The predicate.", "The option to partition.")]
745		///
746		#[document_returns("A pair of options.")]
747		///
748		#[document_examples]
749		///
750		/// ```
751		/// use fp_library::{
752		/// 	brands::*,
753		/// 	functions::*,
754		/// };
755		///
756		/// let x = Some(5);
757		/// let (not_satisfied, satisfied) = partition::<OptionBrand, _>(|a| a > 2, x);
758		/// assert_eq!(satisfied, Some(5));
759		/// assert_eq!(not_satisfied, None);
760		/// ```
761		fn partition<'a, A: 'a + Clone>(
762			func: impl Fn(A) -> bool + 'a,
763			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
764		) -> (
765			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
766			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
767		) {
768			match fa {
769				Some(a) =>
770					if func(a.clone()) {
771						(None, Some(a))
772					} else {
773						(Some(a), None)
774					},
775				None => (None, None),
776			}
777		}
778
779		/// Maps a function over an option and filters out `None` results.
780		///
781		/// This method maps a function over an option and filters out `None` results.
782		#[document_signature]
783		///
784		#[document_type_parameters(
785			"The lifetime of the values.",
786			"The type of the input value.",
787			"The type of the result of applying the function."
788		)]
789		///
790		#[document_parameters("The function to apply.", "The option to filter and map.")]
791		///
792		#[document_returns("The filtered and mapped option.")]
793		///
794		#[document_examples]
795		///
796		/// ```
797		/// use fp_library::{
798		/// 	brands::OptionBrand,
799		/// 	functions::*,
800		/// };
801		///
802		/// let x = Some(5);
803		/// let y = filter_map::<OptionBrand, _, _>(|a| if a > 2 { Some(a * 2) } else { None }, x);
804		/// assert_eq!(y, Some(10));
805		/// ```
806		fn filter_map<'a, A: 'a, B: 'a>(
807			func: impl Fn(A) -> Option<B> + 'a,
808			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
809		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
810			fa.and_then(func)
811		}
812
813		/// Filters an option based on a predicate.
814		///
815		/// This method filters an option based on a predicate.
816		#[document_signature]
817		///
818		#[document_type_parameters("The lifetime of the values.", "The type of the elements.")]
819		///
820		#[document_parameters("The predicate.", "The option to filter.")]
821		///
822		#[document_returns("The filtered option.")]
823		///
824		#[document_examples]
825		///
826		/// ```
827		/// use fp_library::{
828		/// 	brands::OptionBrand,
829		/// 	functions::*,
830		/// };
831		///
832		/// let x = Some(5);
833		/// let y = filter::<OptionBrand, _>(|a| a > 2, x);
834		/// assert_eq!(y, Some(5));
835		/// ```
836		fn filter<'a, A: 'a + Clone>(
837			func: impl Fn(A) -> bool + 'a,
838			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
839		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
840			fa.filter(|a| func(a.clone()))
841		}
842	}
843
844	impl Witherable for OptionBrand {
845		/// Partitions an option based on a function that returns a result in an applicative context.
846		///
847		/// This method partitions an option based on a function that returns a result in an applicative context.
848		#[document_signature]
849		///
850		#[document_type_parameters(
851			"The lifetime of the values.",
852			"The applicative context.",
853			"The type of the elements in the input structure.",
854			"The type of the error values.",
855			"The type of the success values."
856		)]
857		///
858		#[document_parameters(
859			"The function to apply to each element, returning a `Result` in an applicative context.",
860			"The option to partition."
861		)]
862		///
863		#[document_returns("The partitioned option wrapped in the applicative context.")]
864		#[document_examples]
865		///
866		/// ```
867		/// use fp_library::{
868		/// 	brands::*,
869		/// 	functions::*,
870		/// };
871		///
872		/// let x = Some(5);
873		/// let y =
874		/// 	wilt::<OptionBrand, OptionBrand, _, _, _>(|a| Some(if a > 2 { Ok(a) } else { Err(a) }), x);
875		/// assert_eq!(y, Some((None, Some(5))));
876		/// ```
877		fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
878			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
879			+ 'a,
880			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
881		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
882		'a,
883		(
884			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
885			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
886		),
887	>)
888		where
889			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
890			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
891			match ta {
892				Some(a) => M::map(
893					|res| match res {
894						Ok(o) => (None, Some(o)),
895						Err(e) => (Some(e), None),
896					},
897					func(a),
898				),
899				None => M::pure((None, None)),
900			}
901		}
902
903		/// Maps a function over an option and filters out `None` results in an applicative context.
904		///
905		/// This method maps a function over an option and filters out `None` results in an applicative context.
906		#[document_signature]
907		///
908		#[document_type_parameters(
909			"The lifetime of the values.",
910			"The applicative context.",
911			"The type of the elements in the input structure.",
912			"The type of the result of applying the function."
913		)]
914		///
915		#[document_parameters(
916			"The function to apply to each element, returning an `Option` in an applicative context.",
917			"The option to filter and map."
918		)]
919		///
920		#[document_returns("The filtered and mapped option wrapped in the applicative context.")]
921		#[document_examples]
922		///
923		/// ```
924		/// use fp_library::{
925		/// 	brands::*,
926		/// 	functions::*,
927		/// };
928		///
929		/// let x = Some(5);
930		/// let y = wither::<OptionBrand, OptionBrand, _, _>(
931		/// 	|a| Some(if a > 2 { Some(a * 2) } else { None }),
932		/// 	x,
933		/// );
934		/// assert_eq!(y, Some(Some(10)));
935		/// ```
936		fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
937			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
938			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
939		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
940		'a,
941		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
942	>)
943		where
944			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
945			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
946			match ta {
947				Some(a) => func(a),
948				None => M::pure(None),
949			}
950		}
951	}
952}
953
954#[cfg(test)]
955mod tests {
956
957	use {
958		crate::{
959			brands::*,
960			classes::CloneableFn,
961			functions::*,
962		},
963		quickcheck_macros::quickcheck,
964	};
965
966	// Functor Laws
967
968	/// Tests the identity law for Functor.
969	#[quickcheck]
970	fn functor_identity(x: Option<i32>) -> bool {
971		map::<OptionBrand, _, _>(identity, x) == x
972	}
973
974	/// Tests the composition law for Functor.
975	#[quickcheck]
976	fn functor_composition(x: Option<i32>) -> bool {
977		let f = |x: i32| x.wrapping_add(1);
978		let g = |x: i32| x.wrapping_mul(2);
979		map::<OptionBrand, _, _>(compose(f, g), x)
980			== map::<OptionBrand, _, _>(f, map::<OptionBrand, _, _>(g, x))
981	}
982
983	// Applicative Laws
984
985	/// Tests the identity law for Applicative.
986	#[quickcheck]
987	fn applicative_identity(v: Option<i32>) -> bool {
988		apply::<RcFnBrand, OptionBrand, _, _>(
989			pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
990			v,
991		) == v
992	}
993
994	/// Tests the homomorphism law for Applicative.
995	#[quickcheck]
996	fn applicative_homomorphism(x: i32) -> bool {
997		let f = |x: i32| x.wrapping_mul(2);
998		apply::<RcFnBrand, OptionBrand, _, _>(
999			pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1000			pure::<OptionBrand, _>(x),
1001		) == pure::<OptionBrand, _>(f(x))
1002	}
1003
1004	/// Tests the composition law for Applicative.
1005	#[quickcheck]
1006	fn applicative_composition(
1007		w: Option<i32>,
1008		u_is_some: bool,
1009		v_is_some: bool,
1010	) -> bool {
1011		let v_fn = |x: i32| x.wrapping_mul(2);
1012		let u_fn = |x: i32| x.wrapping_add(1);
1013
1014		let v = if v_is_some {
1015			pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(v_fn))
1016		} else {
1017			None
1018		};
1019		let u = if u_is_some {
1020			pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(u_fn))
1021		} else {
1022			None
1023		};
1024
1025		// RHS: u <*> (v <*> w)
1026		let vw = apply::<RcFnBrand, OptionBrand, _, _>(v.clone(), w);
1027		let rhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), vw);
1028
1029		// LHS: pure(compose) <*> u <*> v <*> w
1030		// equivalent to (u . v) <*> w
1031		let uv = match (u, v) {
1032			(Some(uf), Some(vf)) => {
1033				let composed = move |x| uf(vf(x));
1034				Some(<RcFnBrand as CloneableFn>::new(composed))
1035			}
1036			_ => None,
1037		};
1038
1039		let lhs = apply::<RcFnBrand, OptionBrand, _, _>(uv, w);
1040
1041		lhs == rhs
1042	}
1043
1044	/// Tests the interchange law for Applicative.
1045	#[quickcheck]
1046	fn applicative_interchange(y: i32) -> bool {
1047		// u <*> pure y = pure ($ y) <*> u
1048		let f = |x: i32| x.wrapping_mul(2);
1049		let u = pure::<OptionBrand, _>(<RcFnBrand as CloneableFn>::new(f));
1050
1051		let lhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), pure::<OptionBrand, _>(y));
1052
1053		let rhs_fn =
1054			<RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1055		let rhs = apply::<RcFnBrand, OptionBrand, _, _>(pure::<OptionBrand, _>(rhs_fn), u);
1056
1057		lhs == rhs
1058	}
1059
1060	// Monad Laws
1061
1062	/// Tests the left identity law for Monad.
1063	#[quickcheck]
1064	fn monad_left_identity(a: i32) -> bool {
1065		let f = |x: i32| Some(x.wrapping_mul(2));
1066		bind::<OptionBrand, _, _>(pure::<OptionBrand, _>(a), f) == f(a)
1067	}
1068
1069	/// Tests the right identity law for Monad.
1070	#[quickcheck]
1071	fn monad_right_identity(m: Option<i32>) -> bool {
1072		bind::<OptionBrand, _, _>(m, pure::<OptionBrand, _>) == m
1073	}
1074
1075	/// Tests the associativity law for Monad.
1076	#[quickcheck]
1077	fn monad_associativity(m: Option<i32>) -> bool {
1078		let f = |x: i32| Some(x.wrapping_mul(2));
1079		let g = |x: i32| Some(x.wrapping_add(1));
1080		bind::<OptionBrand, _, _>(bind::<OptionBrand, _, _>(m, f), g)
1081			== bind::<OptionBrand, _, _>(m, |x| bind::<OptionBrand, _, _>(f(x), g))
1082	}
1083
1084	// Edge Cases
1085
1086	/// Tests `map` on `None`.
1087	#[test]
1088	fn map_none() {
1089		assert_eq!(map::<OptionBrand, _, _>(|x: i32| x + 1, None), None);
1090	}
1091
1092	/// Tests `bind` on `None`.
1093	#[test]
1094	fn bind_none() {
1095		assert_eq!(bind::<OptionBrand, _, _>(None, |x: i32| Some(x + 1)), None);
1096	}
1097
1098	/// Tests `bind` returning `None`.
1099	#[test]
1100	fn bind_returning_none() {
1101		assert_eq!(bind::<OptionBrand, _, _>(Some(5), |_| None::<i32>), None);
1102	}
1103
1104	/// Tests `fold_right` on `None`.
1105	#[test]
1106	fn fold_right_none() {
1107		assert_eq!(
1108			crate::classes::foldable::fold_right::<RcFnBrand, OptionBrand, _, _>(
1109				|x: i32, acc| x + acc,
1110				0,
1111				None
1112			),
1113			0
1114		);
1115	}
1116
1117	/// Tests `fold_left` on `None`.
1118	#[test]
1119	fn fold_left_none() {
1120		assert_eq!(
1121			crate::classes::foldable::fold_left::<RcFnBrand, OptionBrand, _, _>(
1122				|acc, x: i32| acc + x,
1123				0,
1124				None
1125			),
1126			0
1127		);
1128	}
1129
1130	/// Tests `traverse` on `None`.
1131	#[test]
1132	fn traverse_none() {
1133		assert_eq!(
1134			crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1135				|x: i32| Some(x + 1),
1136				None
1137			),
1138			Some(None)
1139		);
1140	}
1141
1142	/// Tests `traverse` returning `None`.
1143	#[test]
1144	fn traverse_returning_none() {
1145		assert_eq!(
1146			crate::classes::traversable::traverse::<OptionBrand, _, _, OptionBrand>(
1147				|_: i32| None::<i32>,
1148				Some(5)
1149			),
1150			None
1151		);
1152	}
1153
1154	// ParFoldable Tests
1155
1156	/// Tests `par_fold_map` on `None`.
1157	#[test]
1158	fn par_fold_map_none() {
1159		let x: Option<i32> = None;
1160		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1161		assert_eq!(par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x), "".to_string());
1162	}
1163
1164	/// Tests `par_fold_map` on `Some`.
1165	#[test]
1166	fn par_fold_map_some() {
1167		let x = Some(5);
1168		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1169		assert_eq!(par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x), "5".to_string());
1170	}
1171
1172	/// Tests `par_fold_right` on `Some`.
1173	#[test]
1174	fn par_fold_right_some() {
1175		let x = Some(5);
1176		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1177		assert_eq!(par_fold_right::<ArcFnBrand, OptionBrand, _, _>(f, 10, x), 15);
1178	}
1179
1180	// Filterable Laws
1181
1182	/// Tests `filterMap identity ≡ compact`.
1183	#[quickcheck]
1184	fn filterable_filter_map_identity(x: Option<Option<i32>>) -> bool {
1185		filter_map::<OptionBrand, _, _>(identity, x) == compact::<OptionBrand, _>(x)
1186	}
1187
1188	/// Tests `filterMap Just ≡ identity`.
1189	#[quickcheck]
1190	fn filterable_filter_map_just(x: Option<i32>) -> bool {
1191		filter_map::<OptionBrand, _, _>(Some, x) == x
1192	}
1193
1194	/// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
1195	#[quickcheck]
1196	fn filterable_filter_map_composition(x: Option<i32>) -> bool {
1197		let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1198		let l = |i: i32| if i > 5 { Some(i) } else { None };
1199		let composed = |i| r(i).and_then(l);
1200
1201		filter_map::<OptionBrand, _, _>(composed, x)
1202			== filter_map::<OptionBrand, _, _>(l, filter_map::<OptionBrand, _, _>(r, x))
1203	}
1204
1205	/// Tests `filter ≡ filterMap <<< maybeBool`.
1206	#[quickcheck]
1207	fn filterable_filter_consistency(x: Option<i32>) -> bool {
1208		let p = |i: i32| i % 2 == 0;
1209		let maybe_bool = |i| if p(i) { Some(i) } else { None };
1210
1211		filter::<OptionBrand, _>(p, x) == filter_map::<OptionBrand, _, _>(maybe_bool, x)
1212	}
1213
1214	/// Tests `partitionMap identity ≡ separate`.
1215	#[quickcheck]
1216	fn filterable_partition_map_identity(x: Option<Result<i32, i32>>) -> bool {
1217		partition_map::<OptionBrand, _, _, _>(identity, x) == separate::<OptionBrand, _, _>(x)
1218	}
1219
1220	/// Tests `partitionMap Right ≡ identity` (on the right side).
1221	#[quickcheck]
1222	fn filterable_partition_map_right_identity(x: Option<i32>) -> bool {
1223		let (_, oks) = partition_map::<OptionBrand, _, _, _>(Ok::<_, i32>, x);
1224		oks == x
1225	}
1226
1227	/// Tests `partitionMap Left ≡ identity` (on the left side).
1228	#[quickcheck]
1229	fn filterable_partition_map_left_identity(x: Option<i32>) -> bool {
1230		let (errs, _) = partition_map::<OptionBrand, _, _, _>(Err::<i32, _>, x);
1231		errs == x
1232	}
1233
1234	/// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
1235	#[quickcheck]
1236	fn filterable_partition_consistency(x: Option<i32>) -> bool {
1237		let p = |i: i32| i % 2 == 0;
1238		let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1239
1240		let (not_satisfied, satisfied) = partition::<OptionBrand, _>(p, x);
1241		let (errs, oks) = partition_map::<OptionBrand, _, _, _>(either_bool, x);
1242
1243		satisfied == oks && not_satisfied == errs
1244	}
1245
1246	// Witherable Laws
1247
1248	/// Tests `wither (pure <<< Just) ≡ pure`.
1249	#[quickcheck]
1250	fn witherable_identity(x: Option<i32>) -> bool {
1251		wither::<OptionBrand, OptionBrand, _, _>(|i| Some(Some(i)), x) == Some(x)
1252	}
1253
1254	/// Tests `wilt p ≡ map separate <<< traverse p`.
1255	#[quickcheck]
1256	fn witherable_wilt_consistency(x: Option<i32>) -> bool {
1257		let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1258
1259		let lhs = wilt::<OptionBrand, OptionBrand, _, _, _>(p, x);
1260		let rhs = map::<OptionBrand, _, _>(
1261			separate::<OptionBrand, _, _>,
1262			traverse::<OptionBrand, _, _, OptionBrand>(p, x),
1263		);
1264
1265		lhs == rhs
1266	}
1267
1268	/// Tests `wither p ≡ map compact <<< traverse p`.
1269	#[quickcheck]
1270	fn witherable_wither_consistency(x: Option<i32>) -> bool {
1271		let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1272
1273		let lhs = wither::<OptionBrand, OptionBrand, _, _>(p, x);
1274		let rhs = map::<OptionBrand, _, _>(
1275			compact::<OptionBrand, _>,
1276			traverse::<OptionBrand, _, _, OptionBrand>(p, x),
1277		);
1278
1279		lhs == rhs
1280	}
1281
1282	// Edge Cases
1283
1284	/// Tests `compact` on `Some(None)`.
1285	#[test]
1286	fn compact_some_none() {
1287		assert_eq!(compact::<OptionBrand, _>(Some(None::<i32>)), None);
1288	}
1289
1290	/// Tests `compact` on `Some(Some(x))`.
1291	#[test]
1292	fn compact_some_some() {
1293		assert_eq!(compact::<OptionBrand, _>(Some(Some(5))), Some(5));
1294	}
1295
1296	/// Tests `compact` on `None`.
1297	#[test]
1298	fn compact_none() {
1299		assert_eq!(compact::<OptionBrand, _>(None::<Option<i32>>), None);
1300	}
1301
1302	/// Tests `separate` on `Some(Ok(x))`.
1303	#[test]
1304	fn separate_some_ok() {
1305		let (errs, oks) = separate::<OptionBrand, _, _>(Some(Ok::<i32, &str>(5)));
1306		assert_eq!(oks, Some(5));
1307		assert_eq!(errs, None);
1308	}
1309
1310	/// Tests `separate` on `Some(Err(e))`.
1311	#[test]
1312	fn separate_some_err() {
1313		let (errs, oks) = separate::<OptionBrand, _, _>(Some(Err::<i32, &str>("error")));
1314		assert_eq!(oks, None);
1315		assert_eq!(errs, Some("error"));
1316	}
1317
1318	/// Tests `separate` on `None`.
1319	#[test]
1320	fn separate_none() {
1321		let (errs, oks) = separate::<OptionBrand, _, _>(None::<Result<i32, &str>>);
1322		assert_eq!(oks, None);
1323		assert_eq!(errs, None);
1324	}
1325
1326	/// Tests `partition_map` on `None`.
1327	#[test]
1328	fn partition_map_none() {
1329		let (errs, oks) =
1330			partition_map::<OptionBrand, _, _, _>(|x: i32| Ok::<i32, i32>(x), None::<i32>);
1331		assert_eq!(oks, None);
1332		assert_eq!(errs, None);
1333	}
1334
1335	/// Tests `partition` on `None`.
1336	#[test]
1337	fn partition_none() {
1338		let (not_satisfied, satisfied) = partition::<OptionBrand, _>(|x: i32| x > 0, None::<i32>);
1339		assert_eq!(satisfied, None);
1340		assert_eq!(not_satisfied, None);
1341	}
1342
1343	/// Tests `filter_map` on `None`.
1344	#[test]
1345	fn filter_map_none() {
1346		assert_eq!(filter_map::<OptionBrand, _, _>(|x: i32| Some(x), None::<i32>), None);
1347	}
1348
1349	/// Tests `filter` on `None`.
1350	#[test]
1351	fn filter_none() {
1352		assert_eq!(filter::<OptionBrand, _>(|x: i32| x > 0, None::<i32>), None);
1353	}
1354
1355	/// Tests `wilt` on `None`.
1356	#[test]
1357	fn wilt_none() {
1358		let res = wilt::<OptionBrand, OptionBrand, _, _, _>(
1359			|x: i32| Some(Ok::<i32, i32>(x)),
1360			None::<i32>,
1361		);
1362		assert_eq!(res, Some((None, None)));
1363	}
1364
1365	/// Tests `wither` on `None`.
1366	#[test]
1367	fn wither_none() {
1368		let res = wither::<OptionBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), None::<i32>);
1369		assert_eq!(res, Some(None));
1370	}
1371}