Skip to main content

fp_library/dispatch/
witherable.rs

1//! Dispatch for witherable operations:
2//! [`Witherable`](crate::classes::Witherable) and
3//! [`RefWitherable`](crate::classes::RefWitherable).
4//!
5//! Provides the following dispatch traits and unified free functions:
6//!
7//! - [`WiltDispatch`] + [`explicit::wilt`]
8//! - [`WitherDispatch`] + [`explicit::wither`]
9//!
10//! Each routes to the appropriate trait method based on the closure's argument
11//! type.
12//!
13//! ### Examples
14//!
15//! ```
16//! use fp_library::{
17//! 	brands::*,
18//! 	functions::explicit::*,
19//! 	types::*,
20//! };
21//!
22//! // wilt
23//! let y = wilt::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _, _>(
24//! 	|a: i32| Some(if a > 2 { Ok(a) } else { Err(a) }),
25//! 	Some(5),
26//! );
27//! assert_eq!(y, Some((None, Some(5))));
28//!
29//! // wither
30//! let y = wither::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _>(
31//! 	|a: i32| Some(if a > 2 { Some(a * 2) } else { None }),
32//! 	Some(5),
33//! );
34//! assert_eq!(y, Some(Some(10)));
35//! ```
36
37#[fp_macros::document_module]
38pub(crate) mod inner {
39	use {
40		crate::{
41			classes::{
42				Applicative,
43				LiftFn,
44				RefWitherable,
45				Witherable,
46			},
47			dispatch::{
48				Ref,
49				Val,
50			},
51			kinds::*,
52		},
53		fp_macros::*,
54	};
55
56	// -- WiltDispatch --
57
58	/// Trait that routes a wilt operation to the appropriate type class method.
59	///
60	/// The `Marker` type parameter is an implementation detail resolved by
61	/// the compiler from the closure's argument type; callers never specify
62	/// it directly. The `FA` type parameter is inferred from the container
63	/// argument: owned for Val dispatch, borrowed for Ref dispatch.
64	#[document_type_parameters(
65		"The lifetime of the values.",
66		"The brand of the cloneable function to use.",
67		"The brand of the witherable structure.",
68		"The applicative functor brand for the computation.",
69		"The type of the elements in the input structure.",
70		"The error type.",
71		"The success type.",
72		"The container type (owned or borrowed), inferred from the argument.",
73		"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
74	)]
75	#[document_parameters("The closure implementing this dispatch.")]
76	pub trait WiltDispatch<
77		'a,
78		FnBrand,
79		Brand: Kind_cdc7cd43dac7585f,
80		M: Kind_cdc7cd43dac7585f,
81		A: 'a,
82		E: 'a,
83		O: 'a,
84		FA,
85		Marker,
86	> {
87		/// Perform the dispatched wilt operation.
88		#[document_signature]
89		///
90		#[document_parameters("The structure to partition.")]
91		///
92		#[document_returns("The partitioned result in the applicative context.")]
93		#[document_examples]
94		///
95		/// ```
96		/// use fp_library::{
97		/// 	brands::*,
98		/// 	functions::explicit::*,
99		/// 	types::*,
100		/// };
101		///
102		/// let result = wilt::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _, _>(
103		/// 	|a: i32| Some(if a > 2 { Ok(a) } else { Err(a) }),
104		/// 	Some(5),
105		/// );
106		/// assert_eq!(result, Some((None, Some(5))));
107		/// ```
108		fn dispatch(
109			self,
110			ta: FA,
111		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
112			'a,
113			(
114				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
115				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
116			),
117		>);
118	}
119
120	/// Routes `Fn(A) -> M::Of<Result<O, E>>` closures to [`Witherable::wilt`].
121	#[document_type_parameters(
122		"The lifetime of the values.",
123		"The cloneable function brand (unused by Val path).",
124		"The brand of the witherable structure.",
125		"The applicative functor brand.",
126		"The type of the elements in the input structure.",
127		"The error type.",
128		"The success type.",
129		"The closure type."
130	)]
131	#[document_parameters("The closure that takes owned values.")]
132	impl<'a, FnBrand, Brand, M, A, E, O, Func>
133		WiltDispatch<
134			'a,
135			FnBrand,
136			Brand,
137			M,
138			A,
139			E,
140			O,
141			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
142			Val,
143		> for Func
144	where
145		Brand: Witherable,
146		A: 'a + Clone,
147		E: 'a + Clone,
148		O: 'a + Clone,
149		M: Applicative,
150		Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
151		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
152		Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
153	{
154		#[document_signature]
155		///
156		#[document_parameters("The structure to partition.")]
157		///
158		#[document_returns("The partitioned result in the applicative context.")]
159		#[document_examples]
160		///
161		/// ```
162		/// use fp_library::{
163		/// 	brands::*,
164		/// 	functions::explicit::*,
165		/// 	types::*,
166		/// };
167		///
168		/// let result = wilt::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _, _>(
169		/// 	|a: i32| Some(if a > 2 { Ok(a) } else { Err(a) }),
170		/// 	Some(5),
171		/// );
172		/// assert_eq!(result, Some((None, Some(5))));
173		/// ```
174		fn dispatch(
175			self,
176			ta: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
177		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
178			'a,
179			(
180				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
181				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
182			),
183		>) {
184			Brand::wilt::<M, A, E, O>(self, ta)
185		}
186	}
187
188	/// Routes `Fn(&A) -> M::Of<Result<O, E>>` closures to [`RefWitherable::ref_wilt`].
189	///
190	/// The container must be passed by reference (`&ta`).
191	#[document_type_parameters(
192		"The lifetime of the values.",
193		"The borrow lifetime.",
194		"The cloneable function brand.",
195		"The brand of the witherable structure.",
196		"The applicative functor brand.",
197		"The type of the elements in the input structure.",
198		"The error type.",
199		"The success type.",
200		"The closure type."
201	)]
202	#[document_parameters("The closure that takes references.")]
203	impl<'a, 'b, FnBrand, Brand, M, A, E, O, Func>
204		WiltDispatch<
205			'a,
206			FnBrand,
207			Brand,
208			M,
209			A,
210			E,
211			O,
212			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
213			Ref,
214		> for Func
215	where
216		Brand: RefWitherable,
217		FnBrand: LiftFn + 'a,
218		A: 'a + Clone,
219		E: 'a + Clone,
220		O: 'a + Clone,
221		M: Applicative,
222		Func: Fn(&A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>) + 'a,
223		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
224		Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
225	{
226		#[document_signature]
227		///
228		#[document_parameters("A reference to the structure to partition.")]
229		///
230		#[document_returns("The partitioned result in the applicative context.")]
231		#[document_examples]
232		///
233		/// ```
234		/// use fp_library::{
235		/// 	brands::*,
236		/// 	functions::explicit::*,
237		/// 	types::*,
238		/// };
239		///
240		/// let v = vec![1, 2, 3, 4, 5];
241		/// let result: Option<(Vec<i32>, Vec<i32>)> =
242		/// 	wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(
243		/// 		|x: &i32| Some(if *x > 3 { Ok(*x) } else { Err(*x) }),
244		/// 		&v,
245		/// 	);
246		/// assert_eq!(result, Some((vec![1, 2, 3], vec![4, 5])));
247		/// ```
248		fn dispatch(
249			self,
250			ta: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
251		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
252			'a,
253			(
254				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
255				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
256			),
257		>) {
258			Brand::ref_wilt::<FnBrand, M, A, E, O>(self, ta)
259		}
260	}
261
262	// -- WitherDispatch --
263
264	/// Trait that routes a wither operation to the appropriate type class method.
265	///
266	/// The `Marker` type parameter is an implementation detail resolved by
267	/// the compiler from the closure's argument type; callers never specify
268	/// it directly. The `FA` type parameter is inferred from the container
269	/// argument: owned for Val dispatch, borrowed for Ref dispatch.
270	#[document_type_parameters(
271		"The lifetime of the values.",
272		"The brand of the cloneable function to use.",
273		"The brand of the witherable structure.",
274		"The applicative functor brand for the computation.",
275		"The type of the elements in the input structure.",
276		"The type of the elements in the output structure.",
277		"The container type (owned or borrowed), inferred from the argument.",
278		"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
279	)]
280	#[document_parameters("The closure implementing this dispatch.")]
281	pub trait WitherDispatch<
282		'a,
283		FnBrand,
284		Brand: Kind_cdc7cd43dac7585f,
285		M: Kind_cdc7cd43dac7585f,
286		A: 'a,
287		B: 'a,
288		FA,
289		Marker,
290	> {
291		/// Perform the dispatched wither operation.
292		#[document_signature]
293		///
294		#[document_parameters("The structure to filter.")]
295		///
296		#[document_returns("The filtered result in the applicative context.")]
297		#[document_examples]
298		///
299		/// ```
300		/// use fp_library::{
301		/// 	brands::*,
302		/// 	functions::explicit::*,
303		/// };
304		///
305		/// let result = wither::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _>(
306		/// 	|a: i32| Some(if a > 2 { Some(a * 2) } else { None }),
307		/// 	Some(5),
308		/// );
309		/// assert_eq!(result, Some(Some(10)));
310		/// ```
311		fn dispatch(
312			self,
313			ta: FA,
314		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
315			'a,
316			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
317		>);
318	}
319
320	/// Routes `Fn(A) -> M::Of<Option<B>>` closures to [`Witherable::wither`].
321	#[document_type_parameters(
322		"The lifetime of the values.",
323		"The cloneable function brand (unused by Val path).",
324		"The brand of the witherable structure.",
325		"The applicative functor brand.",
326		"The type of the elements in the input structure.",
327		"The type of the elements in the output structure.",
328		"The closure type."
329	)]
330	#[document_parameters("The closure that takes owned values.")]
331	impl<'a, FnBrand, Brand, M, A, B, Func>
332		WitherDispatch<
333			'a,
334			FnBrand,
335			Brand,
336			M,
337			A,
338			B,
339			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
340			Val,
341		> for Func
342	where
343		Brand: Witherable,
344		A: 'a + Clone,
345		B: 'a + Clone,
346		M: Applicative,
347		Func: Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
348		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
349		Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
350	{
351		#[document_signature]
352		///
353		#[document_parameters("The structure to filter.")]
354		///
355		#[document_returns("The filtered result in the applicative context.")]
356		#[document_examples]
357		///
358		/// ```
359		/// use fp_library::{
360		/// 	brands::*,
361		/// 	functions::explicit::*,
362		/// };
363		///
364		/// let result = wither::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _>(
365		/// 	|a: i32| Some(if a > 2 { Some(a * 2) } else { None }),
366		/// 	Some(5),
367		/// );
368		/// assert_eq!(result, Some(Some(10)));
369		/// ```
370		fn dispatch(
371			self,
372			ta: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
373		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
374			'a,
375			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
376		>) {
377			Brand::wither::<M, A, B>(self, ta)
378		}
379	}
380
381	/// Routes `Fn(&A) -> M::Of<Option<B>>` closures to [`RefWitherable::ref_wither`].
382	///
383	/// The container must be passed by reference (`&ta`).
384	#[document_type_parameters(
385		"The lifetime of the values.",
386		"The borrow lifetime.",
387		"The cloneable function brand.",
388		"The brand of the witherable structure.",
389		"The applicative functor brand.",
390		"The type of the elements in the input structure.",
391		"The type of the elements in the output structure.",
392		"The closure type."
393	)]
394	#[document_parameters("The closure that takes references.")]
395	impl<'a, 'b, FnBrand, Brand, M, A, B, Func>
396		WitherDispatch<
397			'a,
398			FnBrand,
399			Brand,
400			M,
401			A,
402			B,
403			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
404			Ref,
405		> for Func
406	where
407		Brand: RefWitherable,
408		FnBrand: LiftFn + 'a,
409		A: 'a + Clone,
410		B: 'a + Clone,
411		M: Applicative,
412		Func: Fn(&A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
413		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
414		Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
415	{
416		#[document_signature]
417		///
418		#[document_parameters("A reference to the structure to filter.")]
419		///
420		#[document_returns("The filtered result in the applicative context.")]
421		#[document_examples]
422		///
423		/// ```
424		/// use fp_library::{
425		/// 	brands::*,
426		/// 	functions::explicit::*,
427		/// };
428		///
429		/// let v = vec![1, 2, 3, 4, 5];
430		/// let result: Option<Vec<i32>> = wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
431		/// 	|x: &i32| if *x > 3 { Some(Some(*x)) } else { Some(None) },
432		/// 	&v,
433		/// );
434		/// assert_eq!(result, Some(vec![4, 5]));
435		/// ```
436		fn dispatch(
437			self,
438			ta: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
439		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
440			'a,
441			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
442		>) {
443			Brand::ref_wither::<FnBrand, M, A, B>(self, ta)
444		}
445	}
446
447	// -- Inference wrappers --
448
449	/// Partitions a structure based on a function returning a Result in an applicative context,
450	/// inferring the brand from the container type.
451	///
452	/// The `Brand` type parameter is inferred from the concrete type of `ta`
453	/// via the `InferableBrand` trait. `FnBrand` and `M` (the applicative brand) must
454	/// still be specified explicitly.
455	/// Both owned and borrowed containers are supported.
456	///
457	/// For types with multiple brands, use
458	/// [`explicit::wilt`](crate::functions::explicit::wilt) with a turbofish.
459	#[document_signature]
460	///
461	#[document_type_parameters(
462		"The lifetime of the values.",
463		"The brand of the cloneable function to use (must be specified explicitly).",
464		"The container type (owned or borrowed). Brand is inferred from this.",
465		"The applicative functor brand (must be specified explicitly).",
466		"The type of the elements in the input structure.",
467		"The error type.",
468		"The success type.",
469		"The brand, inferred via InferableBrand from FA and the closure's input type."
470	)]
471	///
472	#[document_parameters(
473		"The function to apply to each element, returning a Result in an applicative context.",
474		"The witherable structure (owned for Val, borrowed for Ref)."
475	)]
476	///
477	#[document_returns("The partitioned structure wrapped in the applicative context.")]
478	#[document_examples]
479	///
480	/// ```
481	/// use fp_library::{
482	/// 	brands::*,
483	/// 	functions::*,
484	/// };
485	///
486	/// let y = wilt::<RcFnBrand, _, OptionBrand, _, _, _, _>(
487	/// 	|a: i32| Some(if a > 2 { Ok(a) } else { Err(a) }),
488	/// 	Some(5),
489	/// );
490	/// assert_eq!(y, Some((None, Some(5))));
491	/// ```
492	pub fn wilt<'a, FnBrand, FA, M: Kind_cdc7cd43dac7585f, A: 'a, E: 'a, O: 'a, Brand>(
493		func: impl WiltDispatch<
494			'a,
495			FnBrand,
496			Brand,
497			M,
498			A,
499			E,
500			O,
501			FA,
502			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
503		>,
504		ta: FA,
505	) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
506		'a,
507		(
508			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
509			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
510		),
511	>)
512	where
513		Brand: Kind_cdc7cd43dac7585f,
514		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
515		func.dispatch(ta)
516	}
517
518	/// Maps a function over a data structure and filters out None results in an applicative context,
519	/// inferring the brand from the container type.
520	///
521	/// The `Brand` type parameter is inferred from the concrete type of `ta`
522	/// via the `InferableBrand` trait. `FnBrand` and `M` (the applicative brand) must
523	/// still be specified explicitly.
524	/// Both owned and borrowed containers are supported.
525	///
526	/// For types with multiple brands, use
527	/// [`explicit::wither`](crate::functions::explicit::wither) with a turbofish.
528	#[document_signature]
529	///
530	#[document_type_parameters(
531		"The lifetime of the values.",
532		"The brand of the cloneable function to use (must be specified explicitly).",
533		"The container type (owned or borrowed). Brand is inferred from this.",
534		"The applicative functor brand (must be specified explicitly).",
535		"The type of the elements in the input structure.",
536		"The type of the elements in the output structure.",
537		"The brand, inferred via InferableBrand from FA and the closure's input type."
538	)]
539	///
540	#[document_parameters(
541		"The function to apply to each element, returning an Option in an applicative context.",
542		"The witherable structure (owned for Val, borrowed for Ref)."
543	)]
544	///
545	#[document_returns("The filtered structure wrapped in the applicative context.")]
546	#[document_examples]
547	///
548	/// ```
549	/// use fp_library::{
550	/// 	brands::*,
551	/// 	functions::*,
552	/// };
553	///
554	/// let y = wither::<RcFnBrand, _, OptionBrand, _, _, _>(
555	/// 	|a: i32| Some(if a > 2 { Some(a * 2) } else { None }),
556	/// 	Some(5),
557	/// );
558	/// assert_eq!(y, Some(Some(10)));
559	/// ```
560	pub fn wither<'a, FnBrand, FA, M: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, Brand>(
561		func: impl WitherDispatch<
562			'a,
563			FnBrand,
564			Brand,
565			M,
566			A,
567			B,
568			FA,
569			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
570		>,
571		ta: FA,
572	) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
573		'a,
574		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
575	>)
576	where
577		Brand: Kind_cdc7cd43dac7585f,
578		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
579		func.dispatch(ta)
580	}
581
582	// -- Explicit dispatch free functions --
583
584	/// Explicit dispatch functions requiring a Brand turbofish.
585	///
586	/// For most use cases, prefer the inference-enabled wrappers from
587	/// [`functions`](crate::functions).
588	pub mod explicit {
589		use super::*;
590
591		/// Partitions a structure based on a function returning a Result in an applicative context.
592		///
593		/// Dispatches to either [`Witherable::wilt`] or
594		/// [`RefWitherable::ref_wilt`] based on the closure's argument type.
595		///
596		/// The dispatch is resolved at compile time with no runtime cost.
597		#[document_signature]
598		///
599		#[document_type_parameters(
600			"The lifetime of the values.",
601			"The brand of the cloneable function to use.",
602			"The brand of the witherable structure.",
603			"The applicative functor brand for the computation.",
604			"The type of the elements in the input structure.",
605			"The error type.",
606			"The success type.",
607			"The container type (owned or borrowed), inferred from the argument.",
608			"Dispatch marker type, inferred automatically."
609		)]
610		///
611		#[document_parameters(
612			"The function to apply to each element, returning a Result in an applicative context.",
613			"The witherable structure (owned for Val, borrowed for Ref)."
614		)]
615		///
616		#[document_returns("The partitioned structure wrapped in the applicative context.")]
617		///
618		#[document_examples]
619		///
620		/// ```
621		/// use fp_library::{
622		/// 	brands::*,
623		/// 	functions::explicit::*,
624		/// 	types::*,
625		/// };
626		///
627		/// let y = wilt::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _, _>(
628		/// 	|a: i32| Some(if a > 2 { Ok(a) } else { Err(a) }),
629		/// 	Some(5),
630		/// );
631		/// assert_eq!(y, Some((None, Some(5))));
632		/// ```
633		pub fn wilt<
634			'a,
635			FnBrand,
636			Brand: Kind_cdc7cd43dac7585f,
637			M: Kind_cdc7cd43dac7585f,
638			A: 'a,
639			E: 'a,
640			O: 'a,
641			FA,
642			Marker,
643		>(
644			func: impl WiltDispatch<'a, FnBrand, Brand, M, A, E, O, FA, Marker>,
645			ta: FA,
646		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
647			'a,
648			(
649				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
650				Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
651			),
652		>) {
653			func.dispatch(ta)
654		}
655
656		/// Maps a function over a data structure and filters out None results in an applicative context.
657		///
658		/// Dispatches to either [`Witherable::wither`] or
659		/// [`RefWitherable::ref_wither`] based on the closure's argument type.
660		///
661		/// The dispatch is resolved at compile time with no runtime cost.
662		#[document_signature]
663		///
664		#[document_type_parameters(
665			"The lifetime of the values.",
666			"The brand of the cloneable function to use.",
667			"The brand of the witherable structure.",
668			"The applicative functor brand for the computation.",
669			"The type of the elements in the input structure.",
670			"The type of the elements in the output structure.",
671			"The container type (owned or borrowed), inferred from the argument.",
672			"Dispatch marker type, inferred automatically."
673		)]
674		///
675		#[document_parameters(
676			"The function to apply to each element, returning an Option in an applicative context.",
677			"The witherable structure (owned for Val, borrowed for Ref)."
678		)]
679		///
680		#[document_returns("The filtered structure wrapped in the applicative context.")]
681		///
682		#[document_examples]
683		///
684		/// ```
685		/// use fp_library::{
686		/// 	brands::*,
687		/// 	functions::explicit::*,
688		/// };
689		///
690		/// let y = wither::<RcFnBrand, OptionBrand, OptionBrand, _, _, _, _>(
691		/// 	|a: i32| Some(if a > 2 { Some(a * 2) } else { None }),
692		/// 	Some(5),
693		/// );
694		/// assert_eq!(y, Some(Some(10)));
695		/// ```
696		pub fn wither<
697			'a,
698			FnBrand,
699			Brand: Kind_cdc7cd43dac7585f,
700			M: Kind_cdc7cd43dac7585f,
701			A: 'a,
702			B: 'a,
703			FA,
704			Marker,
705		>(
706			func: impl WitherDispatch<'a, FnBrand, Brand, M, A, B, FA, Marker>,
707			ta: FA,
708		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
709			'a,
710			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
711		>) {
712			func.dispatch(ta)
713		}
714	}
715}
716
717pub use inner::*;