Skip to main content

fp_library/dispatch/
filterable.rs

1//! Dispatch for filterable operations:
2//! [`Filterable`](crate::classes::Filterable) and
3//! [`RefFilterable`](crate::classes::RefFilterable).
4//!
5//! Provides the following dispatch traits and unified free functions:
6//!
7//! - [`FilterMapDispatch`] + [`explicit::filter_map`]
8//! - [`FilterDispatch`] + [`explicit::filter`]
9//! - [`PartitionDispatch`] + [`explicit::partition`]
10//! - [`PartitionMapDispatch`] + [`explicit::partition_map`]
11//!
12//! Each routes to the appropriate trait method based on the closure's argument
13//! type.
14//!
15//! ### Examples
16//!
17//! ```
18//! use fp_library::{
19//! 	brands::*,
20//! 	functions::explicit::*,
21//! };
22//!
23//! // filter_map: Owned
24//! let y =
25//! 	filter_map::<OptionBrand, _, _, _, _>(|x: i32| if x > 3 { Some(x) } else { None }, Some(5));
26//! assert_eq!(y, Some(5));
27//!
28//! // filter: Owned
29//! let y = filter::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
30//! assert_eq!(y, Some(5));
31//!
32//! // partition: Owned
33//! let (no, yes) = partition::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
34//! assert_eq!(yes, Some(5));
35//! assert_eq!(no, None);
36//!
37//! // partition_map: Owned
38//! let (errs, oks) =
39//! 	partition_map::<OptionBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x * 2), Some(5));
40//! assert_eq!(errs, None);
41//! assert_eq!(oks, Some(10));
42//! ```
43
44#[fp_macros::document_module]
45pub(crate) mod inner {
46	use {
47		crate::{
48			classes::{
49				Filterable,
50				RefFilterable,
51			},
52			dispatch::{
53				Ref,
54				Val,
55			},
56			kinds::*,
57		},
58		fp_macros::*,
59	};
60
61	// -- FilterMapDispatch --
62
63	/// Trait that routes a filter_map operation to the appropriate type class method.
64	///
65	/// The `Marker` type parameter is an implementation detail resolved by
66	/// the compiler from the closure's argument type; callers never specify
67	/// it directly. The `FA` type parameter is inferred from the container
68	/// argument: owned for Val dispatch, borrowed for Ref dispatch.
69	#[document_type_parameters(
70		"The lifetime of the values.",
71		"The brand of the filterable.",
72		"The type of the value(s) inside the filterable.",
73		"The type of the result(s) of applying the function.",
74		"The container type (owned or borrowed), inferred from the argument.",
75		"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
76	)]
77	#[document_parameters("The closure implementing this dispatch.")]
78	pub trait FilterMapDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker> {
79		/// Perform the dispatched filter_map operation.
80		#[document_signature]
81		///
82		#[document_parameters("The filterable instance containing the value(s).")]
83		///
84		#[document_returns(
85			"A new filterable instance containing only the values for which the function returned `Some`."
86		)]
87		#[document_examples]
88		///
89		/// ```
90		/// use fp_library::{
91		/// 	brands::*,
92		/// 	functions::explicit::*,
93		/// };
94		///
95		/// let result = filter_map::<OptionBrand, _, _, _, _>(
96		/// 	|x: i32| if x > 3 { Some(x * 2) } else { None },
97		/// 	Some(5),
98		/// );
99		/// assert_eq!(result, Some(10));
100		/// ```
101		fn dispatch(
102			self,
103			fa: FA,
104		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>);
105	}
106
107	// -- Val: Fn(A) -> Option<B> -> Filterable::filter_map --
108
109	/// Routes `Fn(A) -> Option<B>` closures to [`Filterable::filter_map`].
110	#[document_type_parameters(
111		"The lifetime of the values.",
112		"The brand of the filterable.",
113		"The type of the value(s) inside the filterable.",
114		"The type of the result(s) of applying the function.",
115		"The closure type."
116	)]
117	#[document_parameters("The closure that takes owned values.")]
118	impl<'a, Brand, A, B, F>
119		FilterMapDispatch<
120			'a,
121			Brand,
122			A,
123			B,
124			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
125			Val,
126		> for F
127	where
128		Brand: Filterable,
129		A: 'a,
130		B: 'a,
131		F: Fn(A) -> Option<B> + 'a,
132	{
133		#[document_signature]
134		///
135		#[document_parameters("The filterable instance containing the value(s).")]
136		///
137		#[document_returns(
138			"A new filterable instance containing only the values for which the function returned `Some`."
139		)]
140		#[document_examples]
141		///
142		/// ```
143		/// use fp_library::{
144		/// 	brands::*,
145		/// 	functions::explicit::*,
146		/// };
147		///
148		/// let result = filter_map::<OptionBrand, _, _, _, _>(
149		/// 	|x: i32| if x > 3 { Some(x * 2) } else { None },
150		/// 	Some(5),
151		/// );
152		/// assert_eq!(result, Some(10));
153		/// ```
154		fn dispatch(
155			self,
156			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
157		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
158			Brand::filter_map(self, fa)
159		}
160	}
161
162	// -- Ref: Fn(&A) -> Option<B> -> RefFilterable::ref_filter_map --
163
164	/// Routes `Fn(&A) -> Option<B>` closures to [`RefFilterable::ref_filter_map`].
165	///
166	/// The container must be passed by reference (`&fa`).
167	#[document_type_parameters(
168		"The lifetime of the values.",
169		"The borrow lifetime.",
170		"The brand of the filterable.",
171		"The type of the value(s) inside the filterable.",
172		"The type of the result(s) of applying the function.",
173		"The closure type."
174	)]
175	#[document_parameters("The closure that takes references.")]
176	impl<'a, 'b, Brand, A, B, F>
177		FilterMapDispatch<
178			'a,
179			Brand,
180			A,
181			B,
182			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
183			Ref,
184		> for F
185	where
186		Brand: RefFilterable,
187		A: 'a,
188		B: 'a,
189		F: Fn(&A) -> Option<B> + 'a,
190	{
191		#[document_signature]
192		///
193		#[document_parameters("A reference to the filterable instance.")]
194		///
195		#[document_returns(
196			"A new filterable instance containing only the values for which the function returned `Some`."
197		)]
198		#[document_examples]
199		///
200		/// ```
201		/// use fp_library::{
202		/// 	brands::*,
203		/// 	functions::explicit::*,
204		/// };
205		///
206		/// let result = filter_map::<OptionBrand, _, _, _, _>(
207		/// 	|x: &i32| if *x > 3 { Some(*x * 2) } else { None },
208		/// 	&Some(5),
209		/// );
210		/// assert_eq!(result, Some(10));
211		/// ```
212		fn dispatch(
213			self,
214			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
215		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
216			Brand::ref_filter_map(self, fa)
217		}
218	}
219
220	// -- FilterDispatch --
221
222	/// Trait that routes a filter operation to the appropriate type class method.
223	///
224	/// The `Marker` type parameter is an implementation detail resolved by
225	/// the compiler from the closure's argument type; callers never specify
226	/// it directly. The `FA` type parameter is inferred from the container
227	/// argument: owned for Val dispatch, borrowed for Ref dispatch.
228	#[document_type_parameters(
229		"The lifetime of the values.",
230		"The brand of the filterable.",
231		"The type of the value(s) inside the filterable.",
232		"The container type (owned or borrowed), inferred from the argument.",
233		"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
234	)]
235	#[document_parameters("The closure implementing this dispatch.")]
236	pub trait FilterDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a + Clone, FA, Marker> {
237		/// Perform the dispatched filter operation.
238		#[document_signature]
239		///
240		#[document_parameters("The filterable instance containing the value(s).")]
241		///
242		#[document_returns(
243			"A new filterable instance containing only the values for which the predicate returned `true`."
244		)]
245		#[document_examples]
246		///
247		/// ```
248		/// use fp_library::{
249		/// 	brands::*,
250		/// 	functions::explicit::*,
251		/// };
252		///
253		/// let result = filter::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
254		/// assert_eq!(result, Some(5));
255		/// ```
256		fn dispatch(
257			self,
258			fa: FA,
259		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>);
260	}
261
262	// -- Val: Fn(A) -> bool -> Filterable::filter --
263
264	/// Routes `Fn(A) -> bool` closures to [`Filterable::filter`].
265	#[document_type_parameters(
266		"The lifetime of the values.",
267		"The brand of the filterable.",
268		"The type of the value(s) inside the filterable.",
269		"The closure type."
270	)]
271	#[document_parameters("The closure that takes owned values.")]
272	impl<'a, Brand, A, F>
273		FilterDispatch<
274			'a,
275			Brand,
276			A,
277			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
278			Val,
279		> for F
280	where
281		Brand: Filterable,
282		A: 'a + Clone,
283		F: Fn(A) -> bool + 'a,
284	{
285		#[document_signature]
286		///
287		#[document_parameters("The filterable instance containing the value(s).")]
288		///
289		#[document_returns(
290			"A new filterable instance containing only the values for which the predicate returned `true`."
291		)]
292		#[document_examples]
293		///
294		/// ```
295		/// use fp_library::{
296		/// 	brands::*,
297		/// 	functions::explicit::*,
298		/// };
299		///
300		/// let result = filter::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
301		/// assert_eq!(result, Some(5));
302		/// ```
303		fn dispatch(
304			self,
305			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
306		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
307			Brand::filter(self, fa)
308		}
309	}
310
311	// -- Ref: Fn(&A) -> bool -> RefFilterable::ref_filter --
312
313	/// Routes `Fn(&A) -> bool` closures to [`RefFilterable::ref_filter`].
314	///
315	/// The container must be passed by reference (`&fa`).
316	#[document_type_parameters(
317		"The lifetime of the values.",
318		"The borrow lifetime.",
319		"The brand of the filterable.",
320		"The type of the value(s) inside the filterable.",
321		"The closure type."
322	)]
323	#[document_parameters("The closure that takes references.")]
324	impl<'a, 'b, Brand, A, F>
325		FilterDispatch<
326			'a,
327			Brand,
328			A,
329			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
330			Ref,
331		> for F
332	where
333		Brand: RefFilterable,
334		A: 'a + Clone,
335		F: Fn(&A) -> bool + 'a,
336	{
337		#[document_signature]
338		///
339		#[document_parameters("A reference to the filterable instance.")]
340		///
341		#[document_returns(
342			"A new filterable instance containing only the values for which the predicate returned `true`."
343		)]
344		#[document_examples]
345		///
346		/// ```
347		/// use fp_library::{
348		/// 	brands::*,
349		/// 	functions::explicit::*,
350		/// };
351		///
352		/// let result = filter::<OptionBrand, _, _, _>(|x: &i32| *x > 3, &Some(5));
353		/// assert_eq!(result, Some(5));
354		/// ```
355		fn dispatch(
356			self,
357			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
358		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
359			Brand::ref_filter(self, fa)
360		}
361	}
362
363	// -- PartitionDispatch --
364
365	/// Trait that routes a partition operation to the appropriate type class method.
366	///
367	/// The `Marker` type parameter is an implementation detail resolved by
368	/// the compiler from the closure's argument type; callers never specify
369	/// it directly. The `FA` type parameter is inferred from the container
370	/// argument: owned for Val dispatch, borrowed for Ref dispatch.
371	#[document_type_parameters(
372		"The lifetime of the values.",
373		"The brand of the filterable.",
374		"The type of the value(s) inside the filterable.",
375		"The container type (owned or borrowed), inferred from the argument.",
376		"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
377	)]
378	#[document_parameters("The closure implementing this dispatch.")]
379	pub trait PartitionDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a + Clone, FA, Marker> {
380		/// Perform the dispatched partition operation.
381		#[document_signature]
382		///
383		#[document_parameters("The filterable instance containing the value(s).")]
384		///
385		#[document_returns(
386			"A tuple of two filterable instances: the first contains elements satisfying the predicate, the second contains the rest."
387		)]
388		#[document_examples]
389		///
390		/// ```
391		/// use fp_library::{
392		/// 	brands::*,
393		/// 	functions::explicit::*,
394		/// };
395		///
396		/// let (no, yes) = partition::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
397		/// assert_eq!(yes, Some(5));
398		/// assert_eq!(no, None);
399		/// ```
400		fn dispatch(
401			self,
402			fa: FA,
403		) -> (
404			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
405			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
406		);
407	}
408
409	// -- Val: Fn(A) -> bool -> Filterable::partition --
410
411	/// Routes `Fn(A) -> bool` closures to [`Filterable::partition`].
412	#[document_type_parameters(
413		"The lifetime of the values.",
414		"The brand of the filterable.",
415		"The type of the value(s) inside the filterable.",
416		"The closure type."
417	)]
418	#[document_parameters("The closure that takes owned values.")]
419	impl<'a, Brand, A, F>
420		PartitionDispatch<
421			'a,
422			Brand,
423			A,
424			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
425			Val,
426		> for F
427	where
428		Brand: Filterable,
429		A: 'a + Clone,
430		F: Fn(A) -> bool + 'a,
431	{
432		#[document_signature]
433		///
434		#[document_parameters("The filterable instance containing the value(s).")]
435		///
436		#[document_returns(
437			"A tuple of two filterable instances: the first contains elements satisfying the predicate, the second contains the rest."
438		)]
439		#[document_examples]
440		///
441		/// ```
442		/// use fp_library::{
443		/// 	brands::*,
444		/// 	functions::explicit::*,
445		/// };
446		///
447		/// let (no, yes) = partition::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
448		/// assert_eq!(yes, Some(5));
449		/// assert_eq!(no, None);
450		/// ```
451		fn dispatch(
452			self,
453			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
454		) -> (
455			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
456			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
457		) {
458			Brand::partition(self, fa)
459		}
460	}
461
462	// -- Ref: Fn(&A) -> bool -> RefFilterable::ref_partition --
463
464	/// Routes `Fn(&A) -> bool` closures to [`RefFilterable::ref_partition`].
465	///
466	/// The container must be passed by reference (`&fa`).
467	#[document_type_parameters(
468		"The lifetime of the values.",
469		"The borrow lifetime.",
470		"The brand of the filterable.",
471		"The type of the value(s) inside the filterable.",
472		"The closure type."
473	)]
474	#[document_parameters("The closure that takes references.")]
475	impl<'a, 'b, Brand, A, F>
476		PartitionDispatch<
477			'a,
478			Brand,
479			A,
480			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
481			Ref,
482		> for F
483	where
484		Brand: RefFilterable,
485		A: 'a + Clone,
486		F: Fn(&A) -> bool + 'a,
487	{
488		#[document_signature]
489		///
490		#[document_parameters("A reference to the filterable instance.")]
491		///
492		#[document_returns(
493			"A tuple of two filterable instances: the first contains elements satisfying the predicate, the second contains the rest."
494		)]
495		#[document_examples]
496		///
497		/// ```
498		/// use fp_library::{
499		/// 	brands::*,
500		/// 	functions::explicit::*,
501		/// };
502		///
503		/// let (no, yes) = partition::<OptionBrand, _, _, _>(|x: &i32| *x > 3, &Some(5));
504		/// assert_eq!(yes, Some(5));
505		/// assert_eq!(no, None);
506		/// ```
507		fn dispatch(
508			self,
509			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
510		) -> (
511			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
512			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
513		) {
514			Brand::ref_partition(self, fa)
515		}
516	}
517
518	// -- PartitionMapDispatch --
519
520	/// Trait that routes a partition_map operation to the appropriate type class method.
521	///
522	/// The `Marker` type parameter is an implementation detail resolved by
523	/// the compiler from the closure's argument type; callers never specify
524	/// it directly. The `FA` type parameter is inferred from the container
525	/// argument: owned for Val dispatch, borrowed for Ref dispatch.
526	#[document_type_parameters(
527		"The lifetime of the values.",
528		"The brand of the filterable.",
529		"The type of the value(s) inside the filterable.",
530		"The error type produced by the partitioning function.",
531		"The success type produced by the partitioning function.",
532		"The container type (owned or borrowed), inferred from the argument.",
533		"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
534	)]
535	#[document_parameters("The closure implementing this dispatch.")]
536	pub trait PartitionMapDispatch<
537		'a,
538		Brand: Kind_cdc7cd43dac7585f,
539		A: 'a,
540		E: 'a,
541		O: 'a,
542		FA,
543		Marker,
544	> {
545		/// Perform the dispatched partition_map operation.
546		#[document_signature]
547		///
548		#[document_parameters("The filterable instance containing the value(s).")]
549		///
550		#[document_returns(
551			"A tuple of two filterable instances: the first contains the `Err` values, the second contains the `Ok` values."
552		)]
553		#[document_examples]
554		///
555		/// ```
556		/// use fp_library::{
557		/// 	brands::*,
558		/// 	functions::explicit::*,
559		/// };
560		///
561		/// let (errs, oks) =
562		/// 	partition_map::<OptionBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x * 2), Some(5));
563		/// assert_eq!(errs, None);
564		/// assert_eq!(oks, Some(10));
565		/// ```
566		fn dispatch(
567			self,
568			fa: FA,
569		) -> (
570			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
571			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
572		);
573	}
574
575	// -- Val: Fn(A) -> Result<O, E> -> Filterable::partition_map --
576
577	/// Routes `Fn(A) -> Result<O, E>` closures to [`Filterable::partition_map`].
578	#[document_type_parameters(
579		"The lifetime of the values.",
580		"The brand of the filterable.",
581		"The type of the value(s) inside the filterable.",
582		"The error type produced by the partitioning function.",
583		"The success type produced by the partitioning function.",
584		"The closure type."
585	)]
586	#[document_parameters("The closure that takes owned values.")]
587	impl<'a, Brand, A, E, O, F>
588		PartitionMapDispatch<
589			'a,
590			Brand,
591			A,
592			E,
593			O,
594			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
595			Val,
596		> for F
597	where
598		Brand: Filterable,
599		A: 'a,
600		E: 'a,
601		O: 'a,
602		F: Fn(A) -> Result<O, E> + 'a,
603	{
604		#[document_signature]
605		///
606		#[document_parameters("The filterable instance containing the value(s).")]
607		///
608		#[document_returns(
609			"A tuple of two filterable instances: the first contains the `Err` values, the second contains the `Ok` values."
610		)]
611		#[document_examples]
612		///
613		/// ```
614		/// use fp_library::{
615		/// 	brands::*,
616		/// 	functions::explicit::*,
617		/// };
618		///
619		/// let (errs, oks) =
620		/// 	partition_map::<OptionBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x * 2), Some(5));
621		/// assert_eq!(errs, None);
622		/// assert_eq!(oks, Some(10));
623		/// ```
624		fn dispatch(
625			self,
626			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
627		) -> (
628			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
629			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
630		) {
631			Brand::partition_map(self, fa)
632		}
633	}
634
635	// -- Ref: Fn(&A) -> Result<O, E> -> RefFilterable::ref_partition_map --
636
637	/// Routes `Fn(&A) -> Result<O, E>` closures to [`RefFilterable::ref_partition_map`].
638	///
639	/// The container must be passed by reference (`&fa`).
640	#[document_type_parameters(
641		"The lifetime of the values.",
642		"The borrow lifetime.",
643		"The brand of the filterable.",
644		"The type of the value(s) inside the filterable.",
645		"The error type produced by the partitioning function.",
646		"The success type produced by the partitioning function.",
647		"The closure type."
648	)]
649	#[document_parameters("The closure that takes references.")]
650	impl<'a, 'b, Brand, A, E, O, F>
651		PartitionMapDispatch<
652			'a,
653			Brand,
654			A,
655			E,
656			O,
657			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
658			Ref,
659		> for F
660	where
661		Brand: RefFilterable,
662		A: 'a,
663		E: 'a,
664		O: 'a,
665		F: Fn(&A) -> Result<O, E> + 'a,
666	{
667		#[document_signature]
668		///
669		#[document_parameters("A reference to the filterable instance.")]
670		///
671		#[document_returns(
672			"A tuple of two filterable instances: the first contains the `Err` values, the second contains the `Ok` values."
673		)]
674		#[document_examples]
675		///
676		/// ```
677		/// use fp_library::{
678		/// 	brands::*,
679		/// 	functions::explicit::*,
680		/// };
681		///
682		/// let (errs, oks) =
683		/// 	partition_map::<OptionBrand, _, _, _, _, _>(|x: &i32| Ok::<i32, i32>(*x * 2), &Some(5));
684		/// assert_eq!(errs, None);
685		/// assert_eq!(oks, Some(10));
686		/// ```
687		fn dispatch(
688			self,
689			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
690		) -> (
691			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
692			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
693		) {
694			Brand::ref_partition_map(self, fa)
695		}
696	}
697
698	// -- Inference wrappers --
699
700	/// Filters the values in a filterable context using a predicate, inferring the brand
701	/// from the container type.
702	///
703	/// The `Brand` type parameter is inferred from the concrete type of `fa`
704	/// via the `InferableBrand` trait. Both owned and borrowed containers are supported.
705	///
706	/// For types with multiple brands, use
707	/// [`explicit::filter`](crate::functions::explicit::filter) with a turbofish.
708	#[document_signature]
709	///
710	#[document_type_parameters(
711		"The lifetime of the values.",
712		"The container type (owned or borrowed). Brand is inferred from this.",
713		"The type of the value(s) inside the filterable.",
714		"The brand, inferred via InferableBrand from FA and the element type."
715	)]
716	///
717	#[document_parameters(
718		"The predicate to apply to each value.",
719		"The filterable instance (owned or borrowed)."
720	)]
721	///
722	#[document_returns(
723		"A new filterable instance containing only the values satisfying the predicate."
724	)]
725	#[document_examples]
726	///
727	/// ```
728	/// use fp_library::functions::*;
729	///
730	/// let y = filter(|x: i32| x > 3, Some(5));
731	/// assert_eq!(y, Some(5));
732	/// ```
733	pub fn filter<'a, FA, A: 'a + Clone, Brand>(
734		f: impl FilterDispatch<
735			'a,
736			Brand,
737			A,
738			FA,
739			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
740		>,
741		fa: FA,
742	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
743	where
744		Brand: Kind_cdc7cd43dac7585f,
745		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
746		f.dispatch(fa)
747	}
748
749	/// Filters and maps the values in a filterable context, inferring the brand
750	/// from the container type.
751	///
752	/// The `Brand` type parameter is inferred from the concrete type of `fa`
753	/// via the `InferableBrand` trait. Both owned and borrowed containers are supported.
754	///
755	/// For types with multiple brands, use
756	/// [`explicit::filter_map`](crate::functions::explicit::filter_map) with a turbofish.
757	#[document_signature]
758	///
759	#[document_type_parameters(
760		"The lifetime of the values.",
761		"The container type (owned or borrowed). Brand is inferred from this.",
762		"The type of the value(s) inside the filterable.",
763		"The type of the result(s) of applying the function.",
764		"The brand, inferred via InferableBrand from FA and the element type."
765	)]
766	///
767	#[document_parameters(
768		"The function to apply to each value. Returns `Some(b)` to keep or `None` to discard.",
769		"The filterable instance (owned or borrowed)."
770	)]
771	///
772	#[document_returns("A new filterable instance containing only the kept values.")]
773	#[document_examples]
774	///
775	/// ```
776	/// use fp_library::functions::*;
777	///
778	/// let y = filter_map(|x: i32| if x > 3 { Some(x) } else { None }, Some(5));
779	/// assert_eq!(y, Some(5));
780	/// ```
781	pub fn filter_map<'a, FA, A: 'a, B: 'a, Brand>(
782		f: impl FilterMapDispatch<
783			'a,
784			Brand,
785			A,
786			B,
787			FA,
788			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
789		>,
790		fa: FA,
791	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
792	where
793		Brand: Kind_cdc7cd43dac7585f,
794		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
795		f.dispatch(fa)
796	}
797
798	/// Partitions the values in a filterable context using a predicate, inferring the brand
799	/// from the container type.
800	///
801	/// The `Brand` type parameter is inferred from the concrete type of `fa`
802	/// via the `InferableBrand` trait. Both owned and borrowed containers are supported.
803	///
804	/// For types with multiple brands, use
805	/// [`explicit::partition`](crate::functions::explicit::partition) with a turbofish.
806	#[document_signature]
807	///
808	#[document_type_parameters(
809		"The lifetime of the values.",
810		"The container type (owned or borrowed). Brand is inferred from this.",
811		"The type of the value(s) inside the filterable.",
812		"The brand, inferred via InferableBrand from FA and the element type."
813	)]
814	///
815	#[document_parameters(
816		"The predicate to apply to each value.",
817		"The filterable instance (owned or borrowed)."
818	)]
819	///
820	#[document_returns("A tuple of two filterable instances split by the predicate.")]
821	#[document_examples]
822	///
823	/// ```
824	/// use fp_library::functions::*;
825	///
826	/// let (no, yes) = partition(|x: i32| x > 3, Some(5));
827	/// assert_eq!(yes, Some(5));
828	/// assert_eq!(no, None);
829	/// ```
830	pub fn partition<'a, FA, A: 'a + Clone, Brand>(
831		f: impl PartitionDispatch<
832			'a,
833			Brand,
834			A,
835			FA,
836			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
837		>,
838		fa: FA,
839	) -> (
840		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
841		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
842	)
843	where
844		Brand: Kind_cdc7cd43dac7585f,
845		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
846		f.dispatch(fa)
847	}
848
849	/// Partitions the values using a function returning `Result`, inferring the brand
850	/// from the container type.
851	///
852	/// The `Brand` type parameter is inferred from the concrete type of `fa`
853	/// via the `InferableBrand` trait. Both owned and borrowed containers are supported.
854	///
855	/// For types with multiple brands, use
856	/// [`explicit::partition_map`](crate::functions::explicit::partition_map) with a turbofish.
857	#[document_signature]
858	///
859	#[document_type_parameters(
860		"The lifetime of the values.",
861		"The container type (owned or borrowed). Brand is inferred from this.",
862		"The type of the value(s) inside the filterable.",
863		"The error type produced by the partitioning function.",
864		"The success type produced by the partitioning function.",
865		"The brand, inferred via InferableBrand from FA and the element type."
866	)]
867	///
868	#[document_parameters(
869		"The function to apply to each value. Returns `Ok(o)` or `Err(e)`.",
870		"The filterable instance (owned or borrowed)."
871	)]
872	///
873	#[document_returns("A tuple of two filterable instances: `Err` values and `Ok` values.")]
874	#[document_examples]
875	///
876	/// ```
877	/// use fp_library::functions::*;
878	///
879	/// let (errs, oks) = partition_map(|x: i32| Ok::<i32, i32>(x * 2), Some(5));
880	/// assert_eq!(errs, None);
881	/// assert_eq!(oks, Some(10));
882	/// ```
883	pub fn partition_map<'a, FA, A: 'a, E: 'a, O: 'a, Brand>(
884		f: impl PartitionMapDispatch<
885			'a,
886			Brand,
887			A,
888			E,
889			O,
890			FA,
891			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
892		>,
893		fa: FA,
894	) -> (
895		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
896		Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
897	)
898	where
899		Brand: Kind_cdc7cd43dac7585f,
900		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
901		f.dispatch(fa)
902	}
903
904	// -- Explicit dispatch free functions --
905
906	/// Explicit dispatch functions requiring a Brand turbofish.
907	///
908	/// For most use cases, prefer the inference-enabled wrappers from
909	/// [`functions`](crate::functions).
910	pub mod explicit {
911		use super::*;
912
913		/// Filters and maps the values in a filterable context.
914		///
915		/// Dispatches to either [`Filterable::filter_map`] or
916		/// [`RefFilterable::ref_filter_map`] based on the closure's argument type:
917		///
918		/// - If the closure takes owned values (`Fn(A) -> Option<B>`) and the
919		///   container is owned, dispatches to [`Filterable::filter_map`].
920		/// - If the closure takes references (`Fn(&A) -> Option<B>`) and the
921		///   container is borrowed (`&fa`), dispatches to
922		///   [`RefFilterable::ref_filter_map`].
923		///
924		/// The `Marker` and `FA` type parameters are inferred automatically by the
925		/// compiler from the closure's argument type and the container argument.
926		/// Callers write `filter_map::<Brand, _, _, _, _>(...)` and never need to
927		/// specify `Marker` or `FA` explicitly.
928		///
929		/// The dispatch is resolved at compile time with no runtime cost.
930		#[document_signature]
931		///
932		#[document_type_parameters(
933			"The lifetime of the values.",
934			"The brand of the filterable.",
935			"The type of the value(s) inside the filterable.",
936			"The type of the result(s) of applying the function.",
937			"The container type (owned or borrowed), inferred from the argument.",
938			"Dispatch marker type, inferred automatically."
939		)]
940		///
941		#[document_parameters(
942			"The function to apply to each value. Returns `Some(b)` to keep the value or `None` to discard it.",
943			"The filterable instance (owned for Val, borrowed for Ref)."
944		)]
945		///
946		#[document_returns(
947			"A new filterable instance containing only the values for which the function returned `Some`."
948		)]
949		///
950		#[document_examples]
951		///
952		/// ```
953		/// use fp_library::{
954		/// 	brands::*,
955		/// 	functions::explicit::*,
956		/// };
957		///
958		/// // Owned: dispatches to Filterable::filter_map
959		/// let y =
960		/// 	filter_map::<OptionBrand, _, _, _, _>(|x: i32| if x > 3 { Some(x) } else { None }, Some(5));
961		/// assert_eq!(y, Some(5));
962		///
963		/// // By-ref: dispatches to RefFilterable::ref_filter_map
964		/// let y = filter_map::<OptionBrand, _, _, _, _>(
965		/// 	|x: &i32| if *x > 3 { Some(*x) } else { None },
966		/// 	&Some(5),
967		/// );
968		/// assert_eq!(y, Some(5));
969		/// ```
970		pub fn filter_map<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker>(
971			f: impl FilterMapDispatch<'a, Brand, A, B, FA, Marker>,
972			fa: FA,
973		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
974			f.dispatch(fa)
975		}
976
977		/// Filters the values in a filterable context using a predicate.
978		///
979		/// Dispatches to either [`Filterable::filter`] or
980		/// [`RefFilterable::ref_filter`] based on the closure's argument type:
981		///
982		/// - If the closure takes owned values (`Fn(A) -> bool`) and the
983		///   container is owned, dispatches to [`Filterable::filter`].
984		/// - If the closure takes references (`Fn(&A) -> bool`) and the
985		///   container is borrowed (`&fa`), dispatches to
986		///   [`RefFilterable::ref_filter`].
987		///
988		/// The `Marker` and `FA` type parameters are inferred automatically by the
989		/// compiler from the closure's argument type and the container argument.
990		/// Callers write `filter::<Brand, _, _, _>(...)` and never need to
991		/// specify `Marker` or `FA` explicitly.
992		///
993		/// The dispatch is resolved at compile time with no runtime cost.
994		#[document_signature]
995		///
996		#[document_type_parameters(
997			"The lifetime of the values.",
998			"The brand of the filterable.",
999			"The type of the value(s) inside the filterable.",
1000			"The container type (owned or borrowed), inferred from the argument.",
1001			"Dispatch marker type, inferred automatically."
1002		)]
1003		///
1004		#[document_parameters(
1005			"The predicate to apply to each value. Returns `true` to keep the value or `false` to discard it.",
1006			"The filterable instance (owned for Val, borrowed for Ref)."
1007		)]
1008		///
1009		#[document_returns(
1010			"A new filterable instance containing only the values for which the predicate returned `true`."
1011		)]
1012		///
1013		#[document_examples]
1014		///
1015		/// ```
1016		/// use fp_library::{
1017		/// 	brands::*,
1018		/// 	functions::explicit::*,
1019		/// };
1020		///
1021		/// // Owned: dispatches to Filterable::filter
1022		/// let y = filter::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
1023		/// assert_eq!(y, Some(5));
1024		///
1025		/// // By-ref: dispatches to RefFilterable::ref_filter
1026		/// let y = filter::<OptionBrand, _, _, _>(|x: &i32| *x > 3, &Some(5));
1027		/// assert_eq!(y, Some(5));
1028		/// ```
1029		pub fn filter<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a + Clone, FA, Marker>(
1030			f: impl FilterDispatch<'a, Brand, A, FA, Marker>,
1031			fa: FA,
1032		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1033			f.dispatch(fa)
1034		}
1035
1036		/// Partitions the values in a filterable context using a predicate.
1037		///
1038		/// Dispatches to either [`Filterable::partition`] or
1039		/// [`RefFilterable::ref_partition`] based on the closure's argument type:
1040		///
1041		/// - If the closure takes owned values (`Fn(A) -> bool`) and the
1042		///   container is owned, dispatches to [`Filterable::partition`].
1043		/// - If the closure takes references (`Fn(&A) -> bool`) and the
1044		///   container is borrowed (`&fa`), dispatches to
1045		///   [`RefFilterable::ref_partition`].
1046		///
1047		/// The `Marker` and `FA` type parameters are inferred automatically by the
1048		/// compiler from the closure's argument type and the container argument.
1049		/// Callers write `partition::<Brand, _, _, _>(...)` and never need to
1050		/// specify `Marker` or `FA` explicitly.
1051		///
1052		/// The dispatch is resolved at compile time with no runtime cost.
1053		#[document_signature]
1054		///
1055		#[document_type_parameters(
1056			"The lifetime of the values.",
1057			"The brand of the filterable.",
1058			"The type of the value(s) inside the filterable.",
1059			"The container type (owned or borrowed), inferred from the argument.",
1060			"Dispatch marker type, inferred automatically."
1061		)]
1062		///
1063		#[document_parameters(
1064			"The predicate to apply to each value. Returns `true` for the first partition or `false` for the second.",
1065			"The filterable instance (owned for Val, borrowed for Ref)."
1066		)]
1067		///
1068		#[document_returns(
1069			"A tuple of two filterable instances: the first contains elements satisfying the predicate, the second contains the rest."
1070		)]
1071		///
1072		#[document_examples]
1073		///
1074		/// ```
1075		/// use fp_library::{
1076		/// 	brands::*,
1077		/// 	functions::explicit::*,
1078		/// };
1079		///
1080		/// // Owned: dispatches to Filterable::partition
1081		/// let (no, yes) = partition::<OptionBrand, _, _, _>(|x: i32| x > 3, Some(5));
1082		/// assert_eq!(yes, Some(5));
1083		/// assert_eq!(no, None);
1084		///
1085		/// // By-ref: dispatches to RefFilterable::ref_partition
1086		/// let (no, yes) = partition::<OptionBrand, _, _, _>(|x: &i32| *x > 3, &Some(5));
1087		/// assert_eq!(yes, Some(5));
1088		/// assert_eq!(no, None);
1089		/// ```
1090		pub fn partition<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a + Clone, FA, Marker>(
1091			f: impl PartitionDispatch<'a, Brand, A, FA, Marker>,
1092			fa: FA,
1093		) -> (
1094			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1095			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1096		) {
1097			f.dispatch(fa)
1098		}
1099
1100		/// Partitions the values in a filterable context using a function that returns `Result`.
1101		///
1102		/// Dispatches to either [`Filterable::partition_map`] or
1103		/// [`RefFilterable::ref_partition_map`] based on the closure's argument type:
1104		///
1105		/// - If the closure takes owned values (`Fn(A) -> Result<O, E>`) and the
1106		///   container is owned, dispatches to [`Filterable::partition_map`].
1107		/// - If the closure takes references (`Fn(&A) -> Result<O, E>`) and the
1108		///   container is borrowed (`&fa`), dispatches to
1109		///   [`RefFilterable::ref_partition_map`].
1110		///
1111		/// The `Marker` and `FA` type parameters are inferred automatically by the
1112		/// compiler from the closure's argument type and the container argument.
1113		/// Callers write `partition_map::<Brand, _, _, _, _, _>(...)` and never need to
1114		/// specify `Marker` or `FA` explicitly.
1115		///
1116		/// The dispatch is resolved at compile time with no runtime cost.
1117		#[document_signature]
1118		///
1119		#[document_type_parameters(
1120			"The lifetime of the values.",
1121			"The brand of the filterable.",
1122			"The type of the value(s) inside the filterable.",
1123			"The error type produced by the partitioning function.",
1124			"The success type produced by the partitioning function.",
1125			"The container type (owned or borrowed), inferred from the argument.",
1126			"Dispatch marker type, inferred automatically."
1127		)]
1128		///
1129		#[document_parameters(
1130			"The function to apply to each value. Returns `Ok(o)` for the success partition or `Err(e)` for the error partition.",
1131			"The filterable instance (owned for Val, borrowed for Ref)."
1132		)]
1133		///
1134		#[document_returns(
1135			"A tuple of two filterable instances: the first contains the `Err` values, the second contains the `Ok` values."
1136		)]
1137		///
1138		#[document_examples]
1139		///
1140		/// ```
1141		/// use fp_library::{
1142		/// 	brands::*,
1143		/// 	functions::explicit::*,
1144		/// };
1145		///
1146		/// // Owned: dispatches to Filterable::partition_map
1147		/// let (errs, oks) =
1148		/// 	partition_map::<OptionBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x * 2), Some(5));
1149		/// assert_eq!(errs, None);
1150		/// assert_eq!(oks, Some(10));
1151		///
1152		/// // By-ref: dispatches to RefFilterable::ref_partition_map
1153		/// let (errs, oks) =
1154		/// 	partition_map::<OptionBrand, _, _, _, _, _>(|x: &i32| Ok::<i32, i32>(*x * 2), &Some(5));
1155		/// assert_eq!(errs, None);
1156		/// assert_eq!(oks, Some(10));
1157		/// ```
1158		pub fn partition_map<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, E: 'a, O: 'a, FA, Marker>(
1159			f: impl PartitionMapDispatch<'a, Brand, A, E, O, FA, Marker>,
1160			fa: FA,
1161		) -> (
1162			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1163			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1164		) {
1165			f.dispatch(fa)
1166		}
1167	}
1168}
1169
1170pub use inner::*;