Skip to main content

fp_library/types/
option.rs

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