fp_library/types/
option.rs

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