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		clonable_fn::ClonableFn, 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_clonable_fn::SendClonableFn, 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 clonable 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(clonable_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 + ClonableFn, B: 'a, A: 'a + Clone>(
197		ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as ClonableFn>::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 clonable 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: ClonableFn + '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 clonable 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: ClonableFn + '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 clonable 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::functions::*;
381	/// use fp_library::brands::{OptionBrand, RcFnBrand};
382	/// use fp_library::types::string; // Import to bring Monoid impl for String into scope
383	///
384	/// let x = Some(5);
385	/// let y = fold_map::<RcFnBrand, OptionBrand, _, _, _>(|a: i32| a.to_string(), x);
386	/// assert_eq!(y, "5".to_string());
387	/// ```
388	fn fold_map<'a, FnBrand, M, A: 'a, Func>(
389		func: Func,
390		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
391	) -> M
392	where
393		M: Monoid + 'a,
394		Func: Fn(A) -> M + 'a,
395		FnBrand: ClonableFn + 'a,
396	{
397		match fa {
398			Some(a) => func(a),
399			None => M::empty(),
400		}
401	}
402}
403
404impl Traversable for OptionBrand {
405	/// Traverses the option with an applicative function.
406	///
407	/// 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)`.
408	///
409	/// ### Type Signature
410	///
411	/// `forall f b a. (Traversable Option, Applicative f) => (a -> f b, Option a) -> f (Option b)`
412	///
413	/// ### Type Parameters
414	///
415	/// * `F`: The applicative context.
416	/// * `B`: The type of the elements in the resulting traversable structure.
417	/// * `A`: The type of the elements in the traversable structure.
418	/// * `Func`: The type of the function to apply.
419	///
420	/// ### Parameters
421	///
422	/// * `func`: The function to apply to each element, returning a value in an applicative context.
423	/// * `ta`: The option to traverse.
424	///
425	/// ### Returns
426	///
427	/// The option wrapped in the applicative context.
428	///
429	/// ### Examples
430	///
431	/// ```
432	/// use fp_library::functions::*;
433	/// use fp_library::brands::OptionBrand;
434	///
435	/// let x = Some(5);
436	/// let y = traverse::<OptionBrand, OptionBrand, _, _, _>(|a| Some(a * 2), x);
437	/// assert_eq!(y, Some(Some(10)));
438	/// ```
439	fn traverse<'a, F: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
440		func: Func,
441		ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
442	) -> 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>)>)
443	where
444		Func: Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
445		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
446	{
447		match ta {
448			Some(a) => F::map(|b| Some(b), func(a)),
449			None => F::pure(None),
450		}
451	}
452	/// Sequences an option of applicative.
453	///
454	/// This method evaluates the computation inside the option and wraps the result in the applicative context. If `None`, it returns `pure(None)`.
455	///
456	/// ### Type Signature
457	///
458	/// `forall f a. (Traversable Option, Applicative f) => (Option (f a)) -> f (Option a)`
459	///
460	/// ### Type Parameters
461	///
462	/// * `F`: The applicative context.
463	/// * `A`: The type of the elements in the traversable structure.
464	///
465	/// ### Parameters
466	///
467	/// * `ta`: The option containing the applicative value.
468	///
469	/// # Returns
470	///
471	/// The option wrapped in the applicative context.
472	///
473	/// ### Examples
474	///
475	/// ```
476	/// use fp_library::functions::*;
477	/// use fp_library::brands::OptionBrand;
478	///
479	/// let x = Some(Some(5));
480	/// let y = sequence::<OptionBrand, OptionBrand, _>(x);
481	/// assert_eq!(y, Some(Some(5)));
482	/// ```
483	fn sequence<'a, F: Applicative, A: 'a + Clone>(
484		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>)>)
485	) -> 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>)>)
486	where
487		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
488		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
489	{
490		match ta {
491			Some(fa) => F::map(|a| Some(a), fa),
492			None => F::pure(None),
493		}
494	}
495}
496
497impl<FnBrand: SendClonableFn> ParFoldable<FnBrand> for OptionBrand {
498	/// Maps the value to a monoid and returns it, or returns empty, in parallel.
499	///
500	/// 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.
501	///
502	/// ### Type Signature
503	///
504	/// `forall fn_brand m a. (ParFoldable Option, Monoid m, Send m, Sync m) => (fn_brand a m, Option a) -> m`
505	///
506	/// ### Type Parameters
507	///
508	/// * `M`: The monoid type (must be `Send + Sync`).
509	/// * `A`: The element type (must be `Send + Sync`).
510	///
511	/// ### Parameters
512	///
513	/// * `func`: The mapping function.
514	/// * `fa`: The option to fold.
515	///
516	/// ### Returns
517	///
518	/// The combined monoid value.
519	///
520	/// ### Examples
521	///
522	/// ```
523	/// use fp_library::functions::*;
524	/// use fp_library::brands::{OptionBrand, ArcFnBrand};
525	///
526	/// let x = Some(1);
527	/// let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
528	/// let y = par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x);
529	/// assert_eq!(y, "1".to_string());
530	/// ```
531	fn par_fold_map<'a, M, A>(
532		func: <FnBrand as SendClonableFn>::SendOf<'a, A, M>,
533		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
534	) -> M
535	where
536		A: 'a + Clone + Send + Sync,
537		M: Monoid + Send + Sync + 'a,
538	{
539		match fa {
540			Some(a) => func(a),
541			None => M::empty(),
542		}
543	}
544}
545
546impl Compactable for OptionBrand {
547	/// Compacts a nested option.
548	///
549	/// This method flattens a nested option.
550	///
551	/// ### Type Signature
552	///
553	/// `forall a. Compactable Option => Option (Option a) -> Option a`
554	///
555	/// ### Type Parameters
556	///
557	/// * `A`: The type of the elements.
558	///
559	/// ### Parameters
560	///
561	/// * `fa`: The nested option.
562	///
563	/// ### Returns
564	///
565	/// The flattened option.
566	///
567	/// ### Examples
568	///
569	/// ```
570	/// use fp_library::functions::*;
571	/// use fp_library::brands::OptionBrand;
572	///
573	/// let x = Some(Some(5));
574	/// let y = compact::<OptionBrand, _>(x);
575	/// assert_eq!(y, Some(5));
576	/// ```
577	fn compact<'a, A: 'a>(
578		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
579			'a,
580			Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
581		>)
582	) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
583		fa.flatten()
584	}
585
586	/// Separates an option of result.
587	///
588	/// This method separates an option of result into a pair of options.
589	///
590	/// ### Type Signature
591	///
592	/// `forall o e. Compactable Option => Option (Result o e) -> (Option o, Option e)`
593	///
594	/// ### Type Parameters
595	///
596	/// * `O`: The type of the success value.
597	/// * `E`: The type of the error value.
598	///
599	/// ### Parameters
600	///
601	/// * `fa`: The option of result.
602	///
603	/// ### Returns
604	///
605	/// A pair of options.
606	///
607	/// ### Examples
608	///
609	/// ```
610	/// use fp_library::functions::*;
611	/// use fp_library::brands::OptionBrand;
612	/// use fp_library::types::Pair;
613	///
614	/// let x: Option<Result<i32, &str>> = Some(Ok(5));
615	/// let Pair(oks, errs) = separate::<OptionBrand, _, _>(x);
616	/// assert_eq!(oks, Some(5));
617	/// assert_eq!(errs, None);
618	/// ```
619	fn separate<'a, O: 'a, E: 'a>(
620		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
621	) -> Pair<
622		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
623		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
624	> {
625		match fa {
626			Some(Ok(o)) => Pair(Some(o), None),
627			Some(Err(e)) => Pair(None, Some(e)),
628			None => Pair(None, None),
629		}
630	}
631}
632
633impl Filterable for OptionBrand {
634	/// Partitions an option based on a function that returns a result.
635	///
636	/// This method partitions an option based on a function that returns a result.
637	///
638	/// ### Type Signature
639	///
640	/// `forall o e a. Filterable Option => (a -> Result o e, Option a) -> Pair (Option o) (Option e)`
641	///
642	/// ### Type Parameters
643	///
644	/// * `O`: The type of the success value.
645	/// * `E`: The type of the error value.
646	/// * `A`: The type of the input value.
647	/// * `Func`: The type of the function to apply.
648	///
649	/// ### Parameters
650	///
651	/// * `func`: The function to apply.
652	/// * `fa`: The option to partition.
653	///
654	/// ### Returns
655	///
656	/// A pair of options.
657	///
658	/// ### Examples
659	///
660	/// ```
661	/// use fp_library::functions::*;
662	/// use fp_library::brands::OptionBrand;
663	/// use fp_library::types::Pair;
664	///
665	/// let x = Some(5);
666	/// let Pair(oks, errs) = partition_map::<OptionBrand, _, _, _, _>(|a| if a > 2 { Ok(a) } else { Err(a) }, x);
667	/// assert_eq!(oks, Some(5));
668	/// assert_eq!(errs, None);
669	/// ```
670	fn partition_map<'a, O: 'a, E: 'a, A: 'a, Func>(
671		func: Func,
672		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
673	) -> Pair<
674		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
675		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
676	>
677	where
678		Func: Fn(A) -> Result<O, E> + 'a,
679	{
680		match fa {
681			Some(a) => match func(a) {
682				Ok(o) => Pair(Some(o), None),
683				Err(e) => Pair(None, Some(e)),
684			},
685			None => Pair(None, None),
686		}
687	}
688	/// Partitions an option based on a predicate.
689	///
690	/// This method partitions an option based on a predicate.
691	///
692	/// ### Type Signature
693	///
694	/// `forall a. Filterable Option => (a -> bool, Option a) -> Pair (Option a) (Option a)`
695	///
696	/// ### Type Parameters
697	///
698	/// * `A`: The type of the elements.
699	/// * `Func`: The type of the predicate.
700	///
701	/// ### Parameters
702	///
703	/// * `func`: The predicate.
704	/// * `fa`: The option to partition.
705	///
706	/// ### Returns
707	///
708	/// A pair of options.
709	///
710	/// ### Examples
711	///
712	/// ```
713	/// use fp_library::functions::*;
714	/// use fp_library::brands::OptionBrand;
715	/// use fp_library::types::Pair;
716	///
717	/// let x = Some(5);
718	/// let Pair(satisfied, not_satisfied) = partition::<OptionBrand, _, _>(|a| a > 2, x);
719	/// assert_eq!(satisfied, Some(5));
720	/// assert_eq!(not_satisfied, None);
721	/// ```
722	fn partition<'a, A: 'a + Clone, Func>(
723		func: Func,
724		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
725	) -> Pair<
726		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
727		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
728	>
729	where
730		Func: Fn(A) -> bool + 'a,
731	{
732		match fa {
733			Some(a) => {
734				if func(a.clone()) {
735					Pair(Some(a), None)
736				} else {
737					Pair(None, Some(a))
738				}
739			}
740			None => Pair(None, None),
741		}
742	}
743
744	/// Maps a function over an option and filters out `None` results.
745	///
746	/// This method maps a function over an option and filters out `None` results.
747	///
748	/// ### Type Signature
749	///
750	/// `forall b a. Filterable Option => (a -> Option b, Option a) -> Option b`
751	///
752	/// ### Type Parameters
753	///
754	/// * `B`: The type of the result of applying the function.
755	/// * `A`: The type of the input value.
756	/// * `Func`: The type of the function to apply.
757	///
758	/// ### Parameters
759	///
760	/// * `func`: The function to apply.
761	/// * `fa`: The option to filter and map.
762	///
763	/// ### Returns
764	///
765	/// The filtered and mapped option.
766	///
767	/// ### Examples
768	///
769	/// ```
770	/// use fp_library::functions::*;
771	/// use fp_library::brands::OptionBrand;
772	///
773	/// let x = Some(5);
774	/// let y = filter_map::<OptionBrand, _, _, _>(|a| if a > 2 { Some(a * 2) } else { None }, x);
775	/// assert_eq!(y, Some(10));
776	/// ```
777	fn filter_map<'a, B: 'a, A: 'a, Func>(
778		func: Func,
779		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
780	) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
781	where
782		Func: Fn(A) -> Option<B> + 'a,
783	{
784		fa.and_then(func)
785	}
786
787	/// Filters an option based on a predicate.
788	///
789	/// This method filters an option based on a predicate.
790	///
791	/// ### Type Signature
792	///
793	/// `forall a. Filterable Option => (a -> bool, Option a) -> Option a`
794	///
795	/// ### Type Parameters
796	///
797	/// * `A`: The type of the elements.
798	/// * `Func`: The type of the predicate.
799	///
800	/// ### Parameters
801	///
802	/// * `func`: The predicate.
803	/// * `fa`: The option to filter.
804	///
805	/// ### Returns
806	///
807	/// The filtered option.
808	///
809	/// ### Examples
810	///
811	/// ```
812	/// use fp_library::functions::*;
813	/// use fp_library::brands::OptionBrand;
814	///
815	/// let x = Some(5);
816	/// let y = filter::<OptionBrand, _, _>(|a| a > 2, x);
817	/// assert_eq!(y, Some(5));
818	/// ```
819	fn filter<'a, A: 'a + Clone, Func>(
820		func: Func,
821		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
822	) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
823	where
824		Func: Fn(A) -> bool + 'a,
825	{
826		fa.filter(|a| func(a.clone()))
827	}
828}
829
830impl Witherable for OptionBrand {
831	/// Partitions an option based on a function that returns a result in an applicative context.
832	///
833	/// This method partitions an option based on a function that returns a result in an applicative context.
834	///
835	/// ### Type Signature
836	///
837	/// `forall m o e a. (Witherable Option, Applicative m) => (a -> m (Result o e), Option a) -> m (Pair (Option o) (Option e))`
838	///
839	/// ### Type Parameters
840	///
841	/// * `M`: The applicative context.
842	/// * `O`: The type of the success values.
843	/// * `E`: The type of the error values.
844	/// * `A`: The type of the elements in the input structure.
845	/// * `Func`: The type of the function to apply.
846	///
847	/// ### Parameters
848	///
849	/// * `func`: The function to apply to each element, returning a `Result` in an applicative context.
850	/// * `ta`: The option to partition.
851	///
852	/// ### Returns
853	///
854	/// The partitioned option wrapped in the applicative context.
855	///
856	/// ### Examples
857	///
858	/// ```
859	/// use fp_library::{functions::*, brands::*, types::*};
860	///
861	/// let x = Some(5);
862	/// let y = wilt::<OptionBrand, OptionBrand, _, _, _, _>(|a| Some(if a > 2 { Ok(a) } else { Err(a) }), x);
863	/// assert_eq!(y, Some(Pair(Some(5), None)));
864	/// ```
865	fn wilt<'a, M: Applicative, O: 'a + Clone, E: 'a + Clone, A: 'a + Clone, Func>(
866		func: Func,
867		ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
868	) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
869		'a,
870		Pair<
871			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
872			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
873		>,
874	>)
875	where
876		Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
877		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
878		Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
879	{
880		match ta {
881			Some(a) => M::map(
882				|res| match res {
883					Ok(o) => Pair(Some(o), None),
884					Err(e) => Pair(None, Some(e)),
885				},
886				func(a),
887			),
888			None => M::pure(Pair(None, None)),
889		}
890	}
891
892	/// Maps a function over an option and filters out `None` results in an applicative context.
893	///
894	/// This method maps a function over an option and filters out `None` results in an applicative context.
895	///
896	/// ### Type Signature
897	///
898	/// `forall m b a. (Witherable Option, Applicative m) => (a -> m (Option b), Option a) -> m (Option b)`
899	///
900	/// ### Type Parameters
901	///
902	/// * `M`: The applicative context.
903	/// * `B`: The type of the result of applying the function.
904	/// * `A`: The type of the elements in the input structure.
905	/// * `Func`: The type of the function to apply.
906	///
907	/// ### Parameters
908	///
909	/// * `func`: The function to apply to each element, returning an `Option` in an applicative context.
910	/// * `ta`: The option to filter and map.
911	///
912	/// ### Returns
913	///
914	/// The filtered and mapped option wrapped in the applicative context.
915	///
916	/// ### Examples
917	///
918	/// ```
919	/// use fp_library::{functions::*, brands::*};
920	///
921	/// let x = Some(5);
922	/// let y = wither::<OptionBrand, OptionBrand, _, _, _>(|a| Some(if a > 2 { Some(a * 2) } else { None }), x);
923	/// assert_eq!(y, Some(Some(10)));
924	/// ```
925	fn wither<'a, M: Applicative, B: 'a + Clone, A: 'a + Clone, Func>(
926		func: Func,
927		ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
928	) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
929		'a,
930		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
931	>)
932	where
933		Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
934		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
935		Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
936	{
937		match ta {
938			Some(a) => func(a),
939			None => M::pure(None),
940		}
941	}
942}
943
944#[cfg(test)]
945mod tests {
946	use super::*;
947	use crate::{brands::*, functions::*};
948	use quickcheck_macros::quickcheck;
949
950	// Functor Laws
951
952	/// Tests the identity law for Functor.
953	#[quickcheck]
954	fn functor_identity(x: Option<i32>) -> bool {
955		map::<OptionBrand, _, _, _>(identity, x) == x
956	}
957
958	/// Tests the composition law for Functor.
959	#[quickcheck]
960	fn functor_composition(x: Option<i32>) -> bool {
961		let f = |x: i32| x.wrapping_add(1);
962		let g = |x: i32| x.wrapping_mul(2);
963		map::<OptionBrand, _, _, _>(compose(f, g), x)
964			== map::<OptionBrand, _, _, _>(f, map::<OptionBrand, _, _, _>(g, x))
965	}
966
967	// Applicative Laws
968
969	/// Tests the identity law for Applicative.
970	#[quickcheck]
971	fn applicative_identity(v: Option<i32>) -> bool {
972		apply::<RcFnBrand, OptionBrand, _, _>(
973			pure::<OptionBrand, _>(<RcFnBrand as ClonableFn>::new(identity)),
974			v,
975		) == v
976	}
977
978	/// Tests the homomorphism law for Applicative.
979	#[quickcheck]
980	fn applicative_homomorphism(x: i32) -> bool {
981		let f = |x: i32| x.wrapping_mul(2);
982		apply::<RcFnBrand, OptionBrand, _, _>(
983			pure::<OptionBrand, _>(<RcFnBrand as ClonableFn>::new(f)),
984			pure::<OptionBrand, _>(x),
985		) == pure::<OptionBrand, _>(f(x))
986	}
987
988	/// Tests the composition law for Applicative.
989	#[quickcheck]
990	fn applicative_composition(
991		w: Option<i32>,
992		u_is_some: bool,
993		v_is_some: bool,
994	) -> bool {
995		let v_fn = |x: i32| x.wrapping_mul(2);
996		let u_fn = |x: i32| x.wrapping_add(1);
997
998		let v = if v_is_some {
999			pure::<OptionBrand, _>(<RcFnBrand as ClonableFn>::new(v_fn))
1000		} else {
1001			None
1002		};
1003		let u = if u_is_some {
1004			pure::<OptionBrand, _>(<RcFnBrand as ClonableFn>::new(u_fn))
1005		} else {
1006			None
1007		};
1008
1009		// RHS: u <*> (v <*> w)
1010		let vw = apply::<RcFnBrand, OptionBrand, _, _>(v.clone(), w.clone());
1011		let rhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), vw);
1012
1013		// LHS: pure(compose) <*> u <*> v <*> w
1014		// equivalent to (u . v) <*> w
1015		let uv = match (u, v) {
1016			(Some(uf), Some(vf)) => {
1017				let composed = move |x| uf(vf(x));
1018				Some(<RcFnBrand as ClonableFn>::new(composed))
1019			}
1020			_ => None,
1021		};
1022
1023		let lhs = apply::<RcFnBrand, OptionBrand, _, _>(uv, w);
1024
1025		lhs == rhs
1026	}
1027
1028	/// Tests the interchange law for Applicative.
1029	#[quickcheck]
1030	fn applicative_interchange(y: i32) -> bool {
1031		// u <*> pure y = pure ($ y) <*> u
1032		let f = |x: i32| x.wrapping_mul(2);
1033		let u = pure::<OptionBrand, _>(<RcFnBrand as ClonableFn>::new(f));
1034
1035		let lhs = apply::<RcFnBrand, OptionBrand, _, _>(u.clone(), pure::<OptionBrand, _>(y));
1036
1037		let rhs_fn = <RcFnBrand as ClonableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1038		let rhs = apply::<RcFnBrand, OptionBrand, _, _>(pure::<OptionBrand, _>(rhs_fn), u);
1039
1040		lhs == rhs
1041	}
1042
1043	// Monad Laws
1044
1045	/// Tests the left identity law for Monad.
1046	#[quickcheck]
1047	fn monad_left_identity(a: i32) -> bool {
1048		let f = |x: i32| Some(x.wrapping_mul(2));
1049		bind::<OptionBrand, _, _, _>(pure::<OptionBrand, _>(a), f) == f(a)
1050	}
1051
1052	/// Tests the right identity law for Monad.
1053	#[quickcheck]
1054	fn monad_right_identity(m: Option<i32>) -> bool {
1055		bind::<OptionBrand, _, _, _>(m, pure::<OptionBrand, _>) == m
1056	}
1057
1058	/// Tests the associativity law for Monad.
1059	#[quickcheck]
1060	fn monad_associativity(m: Option<i32>) -> bool {
1061		let f = |x: i32| Some(x.wrapping_mul(2));
1062		let g = |x: i32| Some(x.wrapping_add(1));
1063		bind::<OptionBrand, _, _, _>(bind::<OptionBrand, _, _, _>(m, f), g)
1064			== bind::<OptionBrand, _, _, _>(m, |x| bind::<OptionBrand, _, _, _>(f(x), g))
1065	}
1066
1067	// Edge Cases
1068
1069	/// Tests `map` on `None`.
1070	#[test]
1071	fn map_none() {
1072		assert_eq!(map::<OptionBrand, _, _, _>(|x: i32| x + 1, None), None);
1073	}
1074
1075	/// Tests `bind` on `None`.
1076	#[test]
1077	fn bind_none() {
1078		assert_eq!(bind::<OptionBrand, _, _, _>(None, |x: i32| Some(x + 1)), None);
1079	}
1080
1081	/// Tests `bind` returning `None`.
1082	#[test]
1083	fn bind_returning_none() {
1084		assert_eq!(bind::<OptionBrand, _, _, _>(Some(5), |_| None::<i32>), None);
1085	}
1086
1087	/// Tests `fold_right` on `None`.
1088	#[test]
1089	fn fold_right_none() {
1090		assert_eq!(
1091			crate::classes::foldable::fold_right::<RcFnBrand, OptionBrand, _, _, _>(
1092				|x: i32, acc| x + acc,
1093				0,
1094				None
1095			),
1096			0
1097		);
1098	}
1099
1100	/// Tests `fold_left` on `None`.
1101	#[test]
1102	fn fold_left_none() {
1103		assert_eq!(
1104			crate::classes::foldable::fold_left::<RcFnBrand, OptionBrand, _, _, _>(
1105				|acc, x: i32| acc + x,
1106				0,
1107				None
1108			),
1109			0
1110		);
1111	}
1112
1113	/// Tests `traverse` on `None`.
1114	#[test]
1115	fn traverse_none() {
1116		assert_eq!(
1117			crate::classes::traversable::traverse::<OptionBrand, OptionBrand, _, _, _>(
1118				|x: i32| Some(x + 1),
1119				None
1120			),
1121			Some(None)
1122		);
1123	}
1124
1125	/// Tests `traverse` returning `None`.
1126	#[test]
1127	fn traverse_returning_none() {
1128		assert_eq!(
1129			crate::classes::traversable::traverse::<OptionBrand, OptionBrand, _, _, _>(
1130				|_: i32| None::<i32>,
1131				Some(5)
1132			),
1133			None
1134		);
1135	}
1136
1137	// ParFoldable Tests
1138
1139	/// Tests `par_fold_map` on `None`.
1140	#[test]
1141	fn par_fold_map_none() {
1142		let x: Option<i32> = None;
1143		let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1144		assert_eq!(par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x), "".to_string());
1145	}
1146
1147	/// Tests `par_fold_map` on `Some`.
1148	#[test]
1149	fn par_fold_map_some() {
1150		let x = Some(5);
1151		let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1152		assert_eq!(par_fold_map::<ArcFnBrand, OptionBrand, _, _>(f, x), "5".to_string());
1153	}
1154
1155	/// Tests `par_fold_right` on `Some`.
1156	#[test]
1157	fn par_fold_right_some() {
1158		let x = Some(5);
1159		let f = send_clonable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1160		assert_eq!(par_fold_right::<ArcFnBrand, OptionBrand, _, _>(f, 10, x), 15);
1161	}
1162
1163	// Filterable Laws
1164
1165	/// Tests `filterMap identity ≡ compact`.
1166	#[quickcheck]
1167	fn filterable_filter_map_identity(x: Option<Option<i32>>) -> bool {
1168		filter_map::<OptionBrand, _, _, _>(identity, x.clone()) == compact::<OptionBrand, _>(x)
1169	}
1170
1171	/// Tests `filterMap Just ≡ identity`.
1172	#[quickcheck]
1173	fn filterable_filter_map_just(x: Option<i32>) -> bool {
1174		filter_map::<OptionBrand, _, _, _>(Some, x.clone()) == x
1175	}
1176
1177	/// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
1178	#[quickcheck]
1179	fn filterable_filter_map_composition(x: Option<i32>) -> bool {
1180		let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1181		let l = |i: i32| if i > 5 { Some(i) } else { None };
1182		let composed = |i| r(i).and_then(l);
1183
1184		filter_map::<OptionBrand, _, _, _>(composed, x.clone())
1185			== filter_map::<OptionBrand, _, _, _>(l, filter_map::<OptionBrand, _, _, _>(r, x))
1186	}
1187
1188	/// Tests `filter ≡ filterMap <<< maybeBool`.
1189	#[quickcheck]
1190	fn filterable_filter_consistency(x: Option<i32>) -> bool {
1191		let p = |i: i32| i % 2 == 0;
1192		let maybe_bool = |i| if p(i) { Some(i) } else { None };
1193
1194		filter::<OptionBrand, _, _>(p, x.clone())
1195			== filter_map::<OptionBrand, _, _, _>(maybe_bool, x)
1196	}
1197
1198	/// Tests `partitionMap identity ≡ separate`.
1199	#[quickcheck]
1200	fn filterable_partition_map_identity(x: Option<Result<i32, i32>>) -> bool {
1201		partition_map::<OptionBrand, _, _, _, _>(identity, x.clone())
1202			== separate::<OptionBrand, _, _>(x)
1203	}
1204
1205	/// Tests `partitionMap Right ≡ identity` (on the right side).
1206	#[quickcheck]
1207	fn filterable_partition_map_right_identity(x: Option<i32>) -> bool {
1208		let Pair(oks, _) = partition_map::<OptionBrand, _, _, _, _>(Ok::<_, i32>, x.clone());
1209		oks == x
1210	}
1211
1212	/// Tests `partitionMap Left ≡ identity` (on the left side).
1213	#[quickcheck]
1214	fn filterable_partition_map_left_identity(x: Option<i32>) -> bool {
1215		let Pair(_, errs) = partition_map::<OptionBrand, _, _, _, _>(Err::<i32, _>, x.clone());
1216		errs == x
1217	}
1218
1219	/// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
1220	#[quickcheck]
1221	fn filterable_partition_consistency(x: Option<i32>) -> bool {
1222		let p = |i: i32| i % 2 == 0;
1223		let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1224
1225		let Pair(satisfied, not_satisfied) = partition::<OptionBrand, _, _>(p, x.clone());
1226		let Pair(oks, errs) = partition_map::<OptionBrand, _, _, _, _>(either_bool, x);
1227
1228		satisfied == oks && not_satisfied == errs
1229	}
1230
1231	// Witherable Laws
1232
1233	/// Tests `wither (pure <<< Just) ≡ pure`.
1234	#[quickcheck]
1235	fn witherable_identity(x: Option<i32>) -> bool {
1236		wither::<OptionBrand, OptionBrand, _, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1237	}
1238
1239	/// Tests `wilt p ≡ map separate <<< traverse p`.
1240	#[quickcheck]
1241	fn witherable_wilt_consistency(x: Option<i32>) -> bool {
1242		let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1243
1244		let lhs = wilt::<OptionBrand, OptionBrand, _, _, _, _>(p, x.clone());
1245		let rhs = map::<OptionBrand, _, _, _>(
1246			|res| separate::<OptionBrand, _, _>(res),
1247			traverse::<OptionBrand, OptionBrand, _, _, _>(p, x),
1248		);
1249
1250		lhs == rhs
1251	}
1252
1253	/// Tests `wither p ≡ map compact <<< traverse p`.
1254	#[quickcheck]
1255	fn witherable_wither_consistency(x: Option<i32>) -> bool {
1256		let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1257
1258		let lhs = wither::<OptionBrand, OptionBrand, _, _, _>(p, x.clone());
1259		let rhs = map::<OptionBrand, _, _, _>(
1260			|opt| compact::<OptionBrand, _>(opt),
1261			traverse::<OptionBrand, OptionBrand, _, _, _>(p, x),
1262		);
1263
1264		lhs == rhs
1265	}
1266
1267	// Edge Cases
1268
1269	/// Tests `compact` on `Some(None)`.
1270	#[test]
1271	fn compact_some_none() {
1272		assert_eq!(compact::<OptionBrand, _>(Some(None::<i32>)), None);
1273	}
1274
1275	/// Tests `compact` on `Some(Some(x))`.
1276	#[test]
1277	fn compact_some_some() {
1278		assert_eq!(compact::<OptionBrand, _>(Some(Some(5))), Some(5));
1279	}
1280
1281	/// Tests `compact` on `None`.
1282	#[test]
1283	fn compact_none() {
1284		assert_eq!(compact::<OptionBrand, _>(None::<Option<i32>>), None);
1285	}
1286
1287	/// Tests `separate` on `Some(Ok(x))`.
1288	#[test]
1289	fn separate_some_ok() {
1290		let Pair(oks, errs) = separate::<OptionBrand, _, _>(Some(Ok::<i32, &str>(5)));
1291		assert_eq!(oks, Some(5));
1292		assert_eq!(errs, None);
1293	}
1294
1295	/// Tests `separate` on `Some(Err(e))`.
1296	#[test]
1297	fn separate_some_err() {
1298		let Pair(oks, errs) = separate::<OptionBrand, _, _>(Some(Err::<i32, &str>("error")));
1299		assert_eq!(oks, None);
1300		assert_eq!(errs, Some("error"));
1301	}
1302
1303	/// Tests `separate` on `None`.
1304	#[test]
1305	fn separate_none() {
1306		let Pair(oks, errs) = separate::<OptionBrand, _, _>(None::<Result<i32, &str>>);
1307		assert_eq!(oks, None);
1308		assert_eq!(errs, None);
1309	}
1310
1311	/// Tests `partition_map` on `None`.
1312	#[test]
1313	fn partition_map_none() {
1314		let Pair(oks, errs) =
1315			partition_map::<OptionBrand, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), None::<i32>);
1316		assert_eq!(oks, None);
1317		assert_eq!(errs, None);
1318	}
1319
1320	/// Tests `partition` on `None`.
1321	#[test]
1322	fn partition_none() {
1323		let Pair(satisfied, not_satisfied) =
1324			partition::<OptionBrand, _, _>(|x: i32| x > 0, None::<i32>);
1325		assert_eq!(satisfied, None);
1326		assert_eq!(not_satisfied, None);
1327	}
1328
1329	/// Tests `filter_map` on `None`.
1330	#[test]
1331	fn filter_map_none() {
1332		assert_eq!(filter_map::<OptionBrand, _, _, _>(|x: i32| Some(x), None::<i32>), None);
1333	}
1334
1335	/// Tests `filter` on `None`.
1336	#[test]
1337	fn filter_none() {
1338		assert_eq!(filter::<OptionBrand, _, _>(|x: i32| x > 0, None::<i32>), None);
1339	}
1340
1341	/// Tests `wilt` on `None`.
1342	#[test]
1343	fn wilt_none() {
1344		let res = wilt::<OptionBrand, OptionBrand, _, _, _, _>(
1345			|x: i32| Some(Ok::<i32, i32>(x)),
1346			None::<i32>,
1347		);
1348		assert_eq!(res, Some(Pair(None, None)));
1349	}
1350
1351	/// Tests `wither` on `None`.
1352	#[test]
1353	fn wither_none() {
1354		let res = wither::<OptionBrand, OptionBrand, _, _, _>(|x: i32| Some(Some(x)), None::<i32>);
1355		assert_eq!(res, Some(None));
1356	}
1357}