Skip to main content

fp_library/types/
option.rs

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