Skip to main content

fp_library/dispatch/
lift.rs

1//! Dispatch for [`Lift::lift2`](crate::classes::Lift::lift2) through
2//! [`explicit::lift5`], and their by-reference counterparts
3//! [`RefLift::ref_lift2`](crate::classes::RefLift::ref_lift2) etc.
4//!
5//! Provides `Lift2Dispatch` through `Lift5Dispatch` traits and unified
6//! [`explicit::lift2`] through [`explicit::lift5`] free functions.
7//!
8//! ### Examples
9//!
10//! ```
11//! use fp_library::{
12//! 	brands::*,
13//! 	functions::explicit::*,
14//! 	types::*,
15//! };
16//!
17//! let z = lift2::<OptionBrand, _, _, _, _, _, _>(|a, b| a + b, Some(1), Some(2));
18//! assert_eq!(z, Some(3));
19//!
20//! let x = RcLazy::pure(3);
21//! let y = RcLazy::pure(4);
22//! let z = lift2::<LazyBrand<RcLazyConfig>, _, _, _, _, _, _>(|a: &i32, b: &i32| *a + *b, &x, &y);
23//! assert_eq!(*z.evaluate(), 7);
24//! ```
25
26#[fp_macros::document_module]
27pub(crate) mod inner {
28	use {
29		crate::{
30			classes::{
31				Lift,
32				RefLift,
33			},
34			dispatch::{
35				Ref,
36				Val,
37			},
38			kinds::*,
39		},
40		fp_macros::*,
41	};
42
43	// -- Lift2Dispatch --
44
45	/// Trait that routes a lift2 operation to the appropriate type class method.
46	///
47	/// `Fn(A, B) -> C` resolves to [`Val`], `Fn(&A, &B) -> C` resolves to [`Ref`].
48	/// The `FA` and `FB` type parameters are inferred from the container arguments:
49	/// owned for Val dispatch, borrowed for Ref dispatch.
50	#[document_type_parameters(
51		"The lifetime of the values.",
52		"The brand of the context.",
53		"The type of the first value.",
54		"The type of the second value.",
55		"The type of the result.",
56		"The first container type (owned or borrowed), inferred from the argument.",
57		"The second container type (owned or borrowed), inferred from the argument.",
58		"Dispatch marker type, inferred automatically."
59	)]
60	#[document_parameters("The closure implementing this dispatch.")]
61	pub trait Lift2Dispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, C: 'a, FA, FB, Marker> {
62		/// Perform the dispatched lift2 operation.
63		#[document_signature]
64		#[document_parameters("The first context.", "The second context.")]
65		#[document_returns("A new context containing the result.")]
66		#[document_examples]
67		///
68		/// ```
69		/// use fp_library::{
70		/// 	brands::*,
71		/// 	functions::explicit::*,
72		/// };
73		/// let z = lift2::<OptionBrand, _, _, _, _, _, _>(|a, b| a + b, Some(1), Some(2));
74		/// assert_eq!(z, Some(3));
75		/// ```
76		fn dispatch(
77			self,
78			fa: FA,
79			fb: FB,
80		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>);
81	}
82
83	/// Routes `Fn(A, B) -> C` closures to [`Lift::lift2`].
84	#[document_type_parameters(
85		"The lifetime.",
86		"The brand.",
87		"The first type.",
88		"The second type.",
89		"The result type.",
90		"The closure type."
91	)]
92	#[document_parameters("The closure that takes owned values.")]
93	impl<'a, Brand, A, B, C, F>
94		Lift2Dispatch<
95			'a,
96			Brand,
97			A,
98			B,
99			C,
100			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
101			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
102			Val,
103		> for F
104	where
105		Brand: Lift,
106		A: Clone + 'a,
107		B: Clone + 'a,
108		C: 'a,
109		F: Fn(A, B) -> C + 'a,
110	{
111		#[document_signature]
112		#[document_parameters("The first context.", "The second context.")]
113		#[document_returns("A new context containing the result.")]
114		#[document_examples]
115		///
116		/// ```
117		/// use fp_library::{
118		/// 	brands::*,
119		/// 	functions::explicit::*,
120		/// };
121		/// let z = lift2::<OptionBrand, _, _, _, _, _, _>(|a, b| a + b, Some(1), Some(2));
122		/// assert_eq!(z, Some(3));
123		/// ```
124		fn dispatch(
125			self,
126			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
127			fb: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
128		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
129			Brand::lift2(self, fa, fb)
130		}
131	}
132
133	/// Routes `Fn(&A, &B) -> C` closures to [`RefLift::ref_lift2`].
134	///
135	/// The containers must be passed by reference (`&fa`, `&fb`).
136	#[document_type_parameters(
137		"The lifetime.",
138		"The borrow lifetime.",
139		"The brand.",
140		"The first type.",
141		"The second type.",
142		"The result type.",
143		"The closure type."
144	)]
145	#[document_parameters("The closure that takes references.")]
146	impl<'a, 'b, Brand, A, B, C, F>
147		Lift2Dispatch<
148			'a,
149			Brand,
150			A,
151			B,
152			C,
153			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
154			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
155			Ref,
156		> for F
157	where
158		Brand: RefLift,
159		A: 'a,
160		B: 'a,
161		C: 'a,
162		F: Fn(&A, &B) -> C + 'a,
163	{
164		#[document_signature]
165		#[document_parameters(
166			"A reference to the first context.",
167			"A reference to the second context."
168		)]
169		#[document_returns("A new context containing the result.")]
170		#[document_examples]
171		///
172		/// ```
173		/// use fp_library::{
174		/// 	brands::*,
175		/// 	functions::explicit::*,
176		/// 	types::*,
177		/// };
178		/// let x = RcLazy::pure(3);
179		/// let y = RcLazy::pure(4);
180		/// let z = lift2::<LazyBrand<RcLazyConfig>, _, _, _, _, _, _>(|a: &i32, b: &i32| *a + *b, &x, &y);
181		/// assert_eq!(*z.evaluate(), 7);
182		/// ```
183		fn dispatch(
184			self,
185			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
186			fb: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
187		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
188			Brand::ref_lift2(self, fa, fb)
189		}
190	}
191
192	// -- Lift3Dispatch --
193
194	/// Trait that routes a lift3 operation to the appropriate type class method.
195	#[document_type_parameters(
196		"The lifetime.",
197		"The brand.",
198		"First type.",
199		"Second type.",
200		"Third type.",
201		"Result type.",
202		"The first container type (owned or borrowed), inferred from the argument.",
203		"The second container type (owned or borrowed), inferred from the argument.",
204		"The third container type (owned or borrowed), inferred from the argument.",
205		"Dispatch marker."
206	)]
207	#[document_parameters("The closure implementing this dispatch.")]
208	pub trait Lift3Dispatch<
209		'a,
210		Brand: Kind_cdc7cd43dac7585f,
211		A: 'a,
212		B: 'a,
213		C: 'a,
214		D: 'a,
215		FA,
216		FB,
217		FC,
218		Marker,
219	> {
220		/// Perform the dispatched lift3 operation.
221		#[document_signature]
222		#[document_parameters("First context.", "Second context.", "Third context.")]
223		#[document_returns("A new context containing the result.")]
224		#[document_examples]
225		///
226		/// ```
227		/// use fp_library::{
228		/// 	brands::*,
229		/// 	functions::explicit::*,
230		/// };
231		/// let r = lift3::<OptionBrand, _, _, _, _, _, _, _, _>(
232		/// 	|a, b, c| a + b + c,
233		/// 	Some(1),
234		/// 	Some(2),
235		/// 	Some(3),
236		/// );
237		/// assert_eq!(r, Some(6));
238		/// ```
239		fn dispatch(
240			self,
241			fa: FA,
242			fb: FB,
243			fc: FC,
244		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>);
245	}
246
247	/// Routes `Fn(A, B, C) -> D` closures through [`Lift::lift2`].
248	#[document_type_parameters(
249		"The lifetime.",
250		"The brand.",
251		"First.",
252		"Second.",
253		"Third.",
254		"Result.",
255		"Closure."
256	)]
257	#[document_parameters("The closure that takes owned values.")]
258	impl<'a, Brand, A, B, C, D, F>
259		Lift3Dispatch<
260			'a,
261			Brand,
262			A,
263			B,
264			C,
265			D,
266			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
267			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
268			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
269			Val,
270		> for F
271	where
272		Brand: Lift,
273		A: Clone + 'a,
274		B: Clone + 'a,
275		C: Clone + 'a,
276		D: 'a,
277		F: Fn(A, B, C) -> D + 'a,
278	{
279		#[document_signature]
280		#[document_parameters("First context.", "Second context.", "Third context.")]
281		#[document_returns("A new context containing the result.")]
282		#[document_examples]
283		///
284		/// ```
285		/// use fp_library::{
286		/// 	brands::*,
287		/// 	functions::explicit::*,
288		/// };
289		/// let r = lift3::<OptionBrand, _, _, _, _, _, _, _, _>(
290		/// 	|a, b, c| a + b + c,
291		/// 	Some(1),
292		/// 	Some(2),
293		/// 	Some(3),
294		/// );
295		/// assert_eq!(r, Some(6));
296		/// ```
297		fn dispatch(
298			self,
299			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
300			fb: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
301			fc: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
302		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) {
303			Brand::lift2(move |(a, b), c| self(a, b, c), Brand::lift2(|a, b| (a, b), fa, fb), fc)
304		}
305	}
306
307	/// Routes `Fn(&A, &B, &C) -> D` closures through [`RefLift::ref_lift2`].
308	///
309	/// The containers must be passed by reference (`&fa`, `&fb`, `&fc`).
310	#[document_type_parameters(
311		"The lifetime.",
312		"The borrow lifetime.",
313		"The brand.",
314		"First.",
315		"Second.",
316		"Third.",
317		"Result.",
318		"Closure."
319	)]
320	#[document_parameters("The closure that takes references.")]
321	impl<'a, 'b, Brand, A, B, C, D, F>
322		Lift3Dispatch<
323			'a,
324			Brand,
325			A,
326			B,
327			C,
328			D,
329			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
330			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
331			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
332			Ref,
333		> for F
334	where
335		Brand: RefLift,
336		A: Clone + 'a,
337		B: Clone + 'a,
338		C: 'a,
339		D: 'a,
340		F: Fn(&A, &B, &C) -> D + 'a,
341	{
342		#[document_signature]
343		#[document_parameters("First context.", "Second context.", "Third context.")]
344		#[document_returns("A new context containing the result.")]
345		#[document_examples]
346		///
347		/// ```
348		/// use fp_library::{
349		/// 	brands::*,
350		/// 	functions::explicit::*,
351		/// 	types::*,
352		/// };
353		/// let a = RcLazy::pure(1);
354		/// let b = RcLazy::pure(2);
355		/// let c = RcLazy::pure(3);
356		/// let r = lift3::<LazyBrand<RcLazyConfig>, _, _, _, _, _, _, _, _>(
357		/// 	|a: &i32, b: &i32, c: &i32| *a + *b + *c,
358		/// 	&a,
359		/// 	&b,
360		/// 	&c,
361		/// );
362		/// assert_eq!(*r.evaluate(), 6);
363		/// ```
364		fn dispatch(
365			self,
366			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
367			fb: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
368			fc: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
369		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) {
370			Brand::ref_lift2(
371				move |(a, b): &(A, B), c: &C| self(a, b, c),
372				&Brand::ref_lift2(|a: &A, b: &B| (a.clone(), b.clone()), fa, fb),
373				fc,
374			)
375		}
376	}
377
378	// -- Lift4Dispatch --
379
380	/// Trait that routes a lift4 operation to the appropriate type class method.
381	#[document_type_parameters(
382		"The lifetime.",
383		"The brand.",
384		"First.",
385		"Second.",
386		"Third.",
387		"Fourth.",
388		"Result.",
389		"The first container type (owned or borrowed), inferred from the argument.",
390		"The second container type (owned or borrowed), inferred from the argument.",
391		"The third container type (owned or borrowed), inferred from the argument.",
392		"The fourth container type (owned or borrowed), inferred from the argument.",
393		"Dispatch marker."
394	)]
395	#[document_parameters("The closure implementing this dispatch.")]
396	pub trait Lift4Dispatch<
397		'a,
398		Brand: Kind_cdc7cd43dac7585f,
399		A: 'a,
400		B: 'a,
401		C: 'a,
402		D: 'a,
403		E: 'a,
404		FA,
405		FB,
406		FC,
407		FD,
408		Marker,
409	> {
410		/// Perform the dispatched lift4 operation.
411		#[document_signature]
412		#[document_parameters("First.", "Second.", "Third.", "Fourth.")]
413		#[document_returns("Result context.")]
414		#[document_examples]
415		///
416		/// ```
417		/// use fp_library::{
418		/// 	brands::*,
419		/// 	functions::explicit::*,
420		/// };
421		/// let r = lift4::<OptionBrand, _, _, _, _, _, _, _, _, _, _>(
422		/// 	|a, b, c, d| a + b + c + d,
423		/// 	Some(1),
424		/// 	Some(2),
425		/// 	Some(3),
426		/// 	Some(4),
427		/// );
428		/// assert_eq!(r, Some(10));
429		/// ```
430		fn dispatch(
431			self,
432			fa: FA,
433			fb: FB,
434			fc: FC,
435			fd: FD,
436		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>);
437	}
438
439	/// Routes `Fn(A, B, C, D) -> E` closures through [`Lift::lift2`].
440	#[document_type_parameters(
441		"The lifetime.",
442		"The brand.",
443		"First.",
444		"Second.",
445		"Third.",
446		"Fourth.",
447		"Result.",
448		"Closure."
449	)]
450	#[document_parameters("The closure that takes owned values.")]
451	impl<'a, Brand, A, B, C, D, E, Func>
452		Lift4Dispatch<
453			'a,
454			Brand,
455			A,
456			B,
457			C,
458			D,
459			E,
460			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
461			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
462			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
463			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
464			Val,
465		> for Func
466	where
467		Brand: Lift,
468		A: Clone + 'a,
469		B: Clone + 'a,
470		C: Clone + 'a,
471		D: Clone + 'a,
472		E: 'a,
473		Func: Fn(A, B, C, D) -> E + 'a,
474	{
475		#[document_signature]
476		#[document_parameters("First.", "Second.", "Third.", "Fourth.")]
477		#[document_returns("Result context.")]
478		#[document_examples]
479		///
480		/// ```
481		/// use fp_library::{
482		/// 	brands::*,
483		/// 	functions::explicit::*,
484		/// };
485		/// let r = lift4::<OptionBrand, _, _, _, _, _, _, _, _, _, _>(
486		/// 	|a, b, c, d| a + b + c + d,
487		/// 	Some(1),
488		/// 	Some(2),
489		/// 	Some(3),
490		/// 	Some(4),
491		/// );
492		/// assert_eq!(r, Some(10));
493		/// ```
494		fn dispatch(
495			self,
496			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
497			fb: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
498			fc: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
499			fd: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
500		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>) {
501			Brand::lift2(
502				move |((a, b), c), d| self(a, b, c, d),
503				Brand::lift2(move |(a, b), c| ((a, b), c), Brand::lift2(|a, b| (a, b), fa, fb), fc),
504				fd,
505			)
506		}
507	}
508
509	/// Routes `Fn(&A, &B, &C, &D) -> E` closures through [`RefLift::ref_lift2`].
510	///
511	/// The containers must be passed by reference.
512	#[document_type_parameters(
513		"The lifetime.",
514		"The borrow lifetime.",
515		"The brand.",
516		"First.",
517		"Second.",
518		"Third.",
519		"Fourth.",
520		"Result.",
521		"Closure."
522	)]
523	#[document_parameters("The closure that takes references.")]
524	impl<'a, 'b, Brand, A, B, C, D, E, Func>
525		Lift4Dispatch<
526			'a,
527			Brand,
528			A,
529			B,
530			C,
531			D,
532			E,
533			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
534			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
535			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
536			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
537			Ref,
538		> for Func
539	where
540		Brand: RefLift,
541		A: Clone + 'a,
542		B: Clone + 'a,
543		C: Clone + 'a,
544		D: 'a,
545		E: 'a,
546		Func: Fn(&A, &B, &C, &D) -> E + 'a,
547	{
548		#[document_signature]
549		#[document_parameters("First.", "Second.", "Third.", "Fourth.")]
550		#[document_returns("Result context.")]
551		#[document_examples]
552		///
553		/// ```
554		/// use fp_library::{
555		/// 	brands::*,
556		/// 	functions::explicit::*,
557		/// 	types::*,
558		/// };
559		/// let a = RcLazy::pure(1);
560		/// let b = RcLazy::pure(2);
561		/// let c = RcLazy::pure(3);
562		/// let d = RcLazy::pure(4);
563		/// let r = lift4::<LazyBrand<RcLazyConfig>, _, _, _, _, _, _, _, _, _, _>(
564		/// 	|a: &i32, b: &i32, c: &i32, d: &i32| *a + *b + *c + *d,
565		/// 	&a,
566		/// 	&b,
567		/// 	&c,
568		/// 	&d,
569		/// );
570		/// assert_eq!(*r.evaluate(), 10);
571		/// ```
572		fn dispatch(
573			self,
574			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
575			fb: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
576			fc: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
577			fd: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
578		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>) {
579			Brand::ref_lift2(
580				move |((a, b), c): &((A, B), C), d: &D| self(a, b, c, d),
581				&Brand::ref_lift2(
582					move |(a, b): &(A, B), c: &C| ((a.clone(), b.clone()), c.clone()),
583					&Brand::ref_lift2(|a: &A, b: &B| (a.clone(), b.clone()), fa, fb),
584					fc,
585				),
586				fd,
587			)
588		}
589	}
590
591	// -- Lift5Dispatch --
592
593	/// Trait that routes a lift5 operation to the appropriate type class method.
594	#[document_type_parameters(
595		"The lifetime.",
596		"The brand.",
597		"1st.",
598		"2nd.",
599		"3rd.",
600		"4th.",
601		"5th.",
602		"Result.",
603		"The first container type (owned or borrowed), inferred from the argument.",
604		"The second container type (owned or borrowed), inferred from the argument.",
605		"The third container type (owned or borrowed), inferred from the argument.",
606		"The fourth container type (owned or borrowed), inferred from the argument.",
607		"The fifth container type (owned or borrowed), inferred from the argument.",
608		"Dispatch marker."
609	)]
610	#[document_parameters("The closure implementing this dispatch.")]
611	pub trait Lift5Dispatch<
612		'a,
613		Brand: Kind_cdc7cd43dac7585f,
614		A: 'a,
615		B: 'a,
616		C: 'a,
617		D: 'a,
618		E: 'a,
619		G: 'a,
620		FA,
621		FB,
622		FC,
623		FD,
624		FE,
625		Marker,
626	> {
627		/// Perform the dispatched lift5 operation.
628		#[document_signature]
629		#[document_parameters("1st.", "2nd.", "3rd.", "4th.", "5th.")]
630		#[document_returns("Result context.")]
631		#[document_examples]
632		///
633		/// ```
634		/// use fp_library::{
635		/// 	brands::*,
636		/// 	functions::explicit::*,
637		/// };
638		/// let r = lift5::<OptionBrand, _, _, _, _, _, _, _, _, _, _, _, _>(
639		/// 	|a, b, c, d, e| a + b + c + d + e,
640		/// 	Some(1),
641		/// 	Some(2),
642		/// 	Some(3),
643		/// 	Some(4),
644		/// 	Some(5),
645		/// );
646		/// assert_eq!(r, Some(15));
647		/// ```
648		fn dispatch(
649			self,
650			fa: FA,
651			fb: FB,
652			fc: FC,
653			fd: FD,
654			fe: FE,
655		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, G>);
656	}
657
658	/// Routes `Fn(A, B, C, D, E) -> G` closures through [`Lift::lift2`].
659	#[document_type_parameters(
660		"The lifetime.",
661		"The brand.",
662		"1st.",
663		"2nd.",
664		"3rd.",
665		"4th.",
666		"5th.",
667		"Result.",
668		"Closure."
669	)]
670	#[document_parameters("The closure that takes owned values.")]
671	impl<'a, Brand, A, B, C, D, E, G, Func>
672		Lift5Dispatch<
673			'a,
674			Brand,
675			A,
676			B,
677			C,
678			D,
679			E,
680			G,
681			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
682			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
683			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
684			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
685			Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
686			Val,
687		> for Func
688	where
689		Brand: Lift,
690		A: Clone + 'a,
691		B: Clone + 'a,
692		C: Clone + 'a,
693		D: Clone + 'a,
694		E: Clone + 'a,
695		G: 'a,
696		Func: Fn(A, B, C, D, E) -> G + 'a,
697	{
698		#[document_signature]
699		#[document_parameters("1st.", "2nd.", "3rd.", "4th.", "5th.")]
700		#[document_returns("Result context.")]
701		#[document_examples]
702		///
703		/// ```
704		/// use fp_library::{
705		/// 	brands::*,
706		/// 	functions::explicit::*,
707		/// };
708		/// let r = lift5::<OptionBrand, _, _, _, _, _, _, _, _, _, _, _, _>(
709		/// 	|a, b, c, d, e| a + b + c + d + e,
710		/// 	Some(1),
711		/// 	Some(2),
712		/// 	Some(3),
713		/// 	Some(4),
714		/// 	Some(5),
715		/// );
716		/// assert_eq!(r, Some(15));
717		/// ```
718		fn dispatch(
719			self,
720			fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
721			fb: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
722			fc: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
723			fd: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
724			fe: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
725		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, G>) {
726			Brand::lift2(
727				move |(((a, b), c), d), e| self(a, b, c, d, e),
728				Brand::lift2(
729					move |((a, b), c), d| (((a, b), c), d),
730					Brand::lift2(
731						move |(a, b), c| ((a, b), c),
732						Brand::lift2(|a, b| (a, b), fa, fb),
733						fc,
734					),
735					fd,
736				),
737				fe,
738			)
739		}
740	}
741
742	/// Routes `Fn(&A, &B, &C, &D, &E) -> G` closures through [`RefLift::ref_lift2`].
743	///
744	/// The containers must be passed by reference.
745	#[document_type_parameters(
746		"The lifetime.",
747		"The borrow lifetime.",
748		"The brand.",
749		"1st.",
750		"2nd.",
751		"3rd.",
752		"4th.",
753		"5th.",
754		"Result.",
755		"Closure."
756	)]
757	#[document_parameters("The closure that takes references.")]
758	impl<'a, 'b, Brand, A, B, C, D, E, G, Func>
759		Lift5Dispatch<
760			'a,
761			Brand,
762			A,
763			B,
764			C,
765			D,
766			E,
767			G,
768			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
769			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
770			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
771			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
772			&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
773			Ref,
774		> for Func
775	where
776		Brand: RefLift,
777		A: Clone + 'a,
778		B: Clone + 'a,
779		C: Clone + 'a,
780		D: Clone + 'a,
781		E: 'a,
782		G: 'a,
783		Func: Fn(&A, &B, &C, &D, &E) -> G + 'a,
784	{
785		#[document_signature]
786		#[document_parameters("1st.", "2nd.", "3rd.", "4th.", "5th.")]
787		#[document_returns("Result context.")]
788		#[document_examples]
789		///
790		/// ```
791		/// use fp_library::{
792		/// 	brands::*,
793		/// 	functions::explicit::*,
794		/// 	types::*,
795		/// };
796		/// let a = RcLazy::pure(1);
797		/// let b = RcLazy::pure(2);
798		/// let c = RcLazy::pure(3);
799		/// let d = RcLazy::pure(4);
800		/// let e = RcLazy::pure(5);
801		/// let r = lift5::<LazyBrand<RcLazyConfig>, _, _, _, _, _, _, _, _, _, _, _, _>(
802		/// 	|a: &i32, b: &i32, c: &i32, d: &i32, e: &i32| *a + *b + *c + *d + *e,
803		/// 	&a,
804		/// 	&b,
805		/// 	&c,
806		/// 	&d,
807		/// 	&e,
808		/// );
809		/// assert_eq!(*r.evaluate(), 15);
810		/// ```
811		fn dispatch(
812			self,
813			fa: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
814			fb: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
815			fc: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>),
816			fd: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>),
817			fe: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
818		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, G>) {
819			Brand::ref_lift2(
820				move |(((a, b), c), d): &(((A, B), C), D), e: &E| self(a, b, c, d, e),
821				&Brand::ref_lift2(
822					move |((a, b), c): &((A, B), C), d: &D| {
823						(((a.clone(), b.clone()), c.clone()), d.clone())
824					},
825					&Brand::ref_lift2(
826						move |(a, b): &(A, B), c: &C| ((a.clone(), b.clone()), c.clone()),
827						&Brand::ref_lift2(|a: &A, b: &B| (a.clone(), b.clone()), fa, fb),
828						fc,
829					),
830					fd,
831				),
832				fe,
833			)
834		}
835	}
836
837	// -- Inference wrappers --
838
839	/// Lifts a binary function into a functor context, inferring the brand
840	/// from the first container type.
841	///
842	/// The `Brand` type parameter is inferred from the concrete type of `fa`
843	/// via the `InferableBrand` trait. The dispatch trait constrains `fb` to the same brand.
844	///
845	/// For types with multiple brands, use
846	/// [`explicit::lift2`](crate::functions::explicit::lift2) with a turbofish.
847	#[document_signature]
848	///
849	#[document_type_parameters(
850		"The lifetime of the values.",
851		"The first container type. Brand is inferred from this.",
852		"The second container type.",
853		"The type of the first value.",
854		"The type of the second value.",
855		"The type of the result.",
856		"The brand, inferred via InferableBrand from FA and the closure's input type."
857	)]
858	///
859	#[document_parameters(
860		"The function to lift.",
861		"The first context (owned or borrowed).",
862		"The second context (owned or borrowed)."
863	)]
864	///
865	#[document_returns("A new context containing the result of applying the function.")]
866	#[document_examples]
867	///
868	/// ```
869	/// use fp_library::functions::*;
870	///
871	/// let z = lift2(|a, b| a + b, Some(1), Some(2));
872	/// assert_eq!(z, Some(3));
873	/// ```
874	pub fn lift2<'a, FA, FB, A: 'a, B: 'a, C: 'a, Brand>(
875		f: impl Lift2Dispatch<
876			'a,
877			Brand,
878			A,
879			B,
880			C,
881			FA,
882			FB,
883			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
884		>,
885		fa: FA,
886		fb: FB,
887	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
888	where
889		Brand: Kind_cdc7cd43dac7585f,
890		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
891		f.dispatch(fa, fb)
892	}
893
894	/// Lifts a ternary function into a functor context, inferring the brand
895	/// from the first container type.
896	///
897	/// The `Brand` type parameter is inferred from the concrete type of `fa`
898	/// via the `InferableBrand` trait. The dispatch trait constrains all other containers
899	/// to the same brand.
900	///
901	/// For types with multiple brands, use
902	/// [`explicit::lift3`](crate::functions::explicit::lift3) with a turbofish.
903	#[document_signature]
904	///
905	#[document_type_parameters(
906		"The lifetime of the values.",
907		"The first container type. Brand is inferred from this.",
908		"The second container type.",
909		"The third container type.",
910		"The type of the first value.",
911		"The type of the second value.",
912		"The type of the third value.",
913		"The type of the result.",
914		"The brand, inferred via InferableBrand from FA and the closure's input type."
915	)]
916	///
917	#[document_parameters(
918		"The function to lift.",
919		"First context (owned or borrowed).",
920		"Second context (owned or borrowed).",
921		"Third context (owned or borrowed)."
922	)]
923	///
924	#[document_returns("A new context containing the result.")]
925	#[document_examples]
926	///
927	/// ```
928	/// use fp_library::functions::*;
929	///
930	/// let r = lift3(|a, b, c| a + b + c, Some(1), Some(2), Some(3));
931	/// assert_eq!(r, Some(6));
932	/// ```
933	pub fn lift3<'a, FA, FB, FC, A: 'a, B: 'a, C: 'a, D: 'a, Brand>(
934		f: impl Lift3Dispatch<
935			'a,
936			Brand,
937			A,
938			B,
939			C,
940			D,
941			FA,
942			FB,
943			FC,
944			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
945		>,
946		fa: FA,
947		fb: FB,
948		fc: FC,
949	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>)
950	where
951		Brand: Kind_cdc7cd43dac7585f,
952		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
953		f.dispatch(fa, fb, fc)
954	}
955
956	/// Lifts a quaternary function into a functor context, inferring the brand
957	/// from the first container type.
958	///
959	/// The `Brand` type parameter is inferred from the concrete type of `fa`
960	/// via the `InferableBrand` trait. The dispatch trait constrains all other containers
961	/// to the same brand.
962	///
963	/// For types with multiple brands, use
964	/// [`explicit::lift4`](crate::functions::explicit::lift4) with a turbofish.
965	#[document_signature]
966	///
967	#[document_type_parameters(
968		"The lifetime of the values.",
969		"The first container type. Brand is inferred from this.",
970		"The second container type.",
971		"The third container type.",
972		"The fourth container type.",
973		"The type of the first value.",
974		"The type of the second value.",
975		"The type of the third value.",
976		"The type of the fourth value.",
977		"The type of the result.",
978		"The brand, inferred via InferableBrand from FA and the closure's input type."
979	)]
980	///
981	#[document_parameters(
982		"The function to lift.",
983		"First context (owned or borrowed).",
984		"Second context (owned or borrowed).",
985		"Third context (owned or borrowed).",
986		"Fourth context (owned or borrowed)."
987	)]
988	///
989	#[document_returns("A new context containing the result.")]
990	#[document_examples]
991	///
992	/// ```
993	/// use fp_library::functions::*;
994	///
995	/// let r = lift4(|a, b, c, d| a + b + c + d, Some(1), Some(2), Some(3), Some(4));
996	/// assert_eq!(r, Some(10));
997	/// ```
998	pub fn lift4<'a, FA, FB, FC, FD, A: 'a, B: 'a, C: 'a, D: 'a, E: 'a, Brand>(
999		f: impl Lift4Dispatch<
1000			'a,
1001			Brand,
1002			A,
1003			B,
1004			C,
1005			D,
1006			E,
1007			FA,
1008			FB,
1009			FC,
1010			FD,
1011			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
1012		>,
1013		fa: FA,
1014		fb: FB,
1015		fc: FC,
1016		fd: FD,
1017	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>)
1018	where
1019		Brand: Kind_cdc7cd43dac7585f,
1020		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
1021		f.dispatch(fa, fb, fc, fd)
1022	}
1023
1024	/// Lifts a quinary function into a functor context, inferring the brand
1025	/// from the first container type.
1026	///
1027	/// The `Brand` type parameter is inferred from the concrete type of `fa`
1028	/// via the `InferableBrand` trait. The dispatch trait constrains all other containers
1029	/// to the same brand.
1030	///
1031	/// For types with multiple brands, use
1032	/// [`explicit::lift5`](crate::functions::explicit::lift5) with a turbofish.
1033	#[document_signature]
1034	///
1035	#[document_type_parameters(
1036		"The lifetime of the values.",
1037		"The first container type. Brand is inferred from this.",
1038		"The second container type.",
1039		"The third container type.",
1040		"The fourth container type.",
1041		"The fifth container type.",
1042		"The type of the first value.",
1043		"The type of the second value.",
1044		"The type of the third value.",
1045		"The type of the fourth value.",
1046		"The type of the fifth value.",
1047		"The type of the result.",
1048		"The brand, inferred via InferableBrand from FA and the closure's input type."
1049	)]
1050	///
1051	#[document_parameters(
1052		"The function to lift.",
1053		"1st context (owned or borrowed).",
1054		"2nd context (owned or borrowed).",
1055		"3rd context (owned or borrowed).",
1056		"4th context (owned or borrowed).",
1057		"5th context (owned or borrowed)."
1058	)]
1059	///
1060	#[document_returns("A new context containing the result.")]
1061	#[document_examples]
1062	///
1063	/// ```
1064	/// use fp_library::functions::*;
1065	///
1066	/// let r = lift5(|a, b, c, d, e| a + b + c + d + e, Some(1), Some(2), Some(3), Some(4), Some(5));
1067	/// assert_eq!(r, Some(15));
1068	/// ```
1069	pub fn lift5<'a, FA, FB, FC, FD, FE, A: 'a, B: 'a, C: 'a, D: 'a, E: 'a, G: 'a, Brand>(
1070		f: impl Lift5Dispatch<
1071			'a,
1072			Brand,
1073			A,
1074			B,
1075			C,
1076			D,
1077			E,
1078			G,
1079			FA,
1080			FB,
1081			FC,
1082			FD,
1083			FE,
1084			<FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
1085		>,
1086		fa: FA,
1087		fb: FB,
1088		fc: FC,
1089		fd: FD,
1090		fe: FE,
1091	) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, G>)
1092	where
1093		Brand: Kind_cdc7cd43dac7585f,
1094		FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
1095		f.dispatch(fa, fb, fc, fd, fe)
1096	}
1097
1098	// -- Explicit dispatch free functions --
1099
1100	/// Explicit dispatch functions requiring a Brand turbofish.
1101	///
1102	/// For most use cases, prefer the inference-enabled wrappers from
1103	/// [`functions`](crate::functions).
1104	pub mod explicit {
1105		use super::*;
1106
1107		/// Lifts a binary function into a functor context.
1108		///
1109		/// Dispatches to either [`Lift::lift2`] or [`RefLift::ref_lift2`]
1110		/// based on the closure's argument types.
1111		///
1112		/// The `Marker`, `FA`, and `FB` type parameters are inferred automatically
1113		/// by the compiler from the closure's argument types and the container
1114		/// arguments.
1115		#[document_signature]
1116		///
1117		#[document_type_parameters(
1118			"The lifetime of the values.",
1119			"The brand of the context.",
1120			"The type of the first value.",
1121			"The type of the second value.",
1122			"The type of the result.",
1123			"The first container type (owned or borrowed), inferred from the argument.",
1124			"The second container type (owned or borrowed), inferred from the argument.",
1125			"Dispatch marker type, inferred automatically."
1126		)]
1127		///
1128		#[document_parameters(
1129			"The function to lift.",
1130			"The first context (owned for Val, borrowed for Ref).",
1131			"The second context (owned for Val, borrowed for Ref)."
1132		)]
1133		///
1134		#[document_returns("A new context containing the result of applying the function.")]
1135		#[document_examples]
1136		///
1137		/// ```
1138		/// use fp_library::{
1139		/// 	brands::*,
1140		/// 	functions::explicit::*,
1141		/// };
1142		/// let z = lift2::<OptionBrand, _, _, _, _, _, _>(|a, b| a + b, Some(1), Some(2));
1143		/// assert_eq!(z, Some(3));
1144		/// ```
1145		pub fn lift2<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, C: 'a, FA, FB, Marker>(
1146			f: impl Lift2Dispatch<'a, Brand, A, B, C, FA, FB, Marker>,
1147			fa: FA,
1148			fb: FB,
1149		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1150			f.dispatch(fa, fb)
1151		}
1152
1153		/// Lifts a ternary function into a functor context.
1154		///
1155		/// Dispatches to [`Lift::lift2`] or [`RefLift::ref_lift2`] based on the closure's argument types.
1156		///
1157		/// When dispatched through the Ref path (`Fn(&A, &B, &C) -> D`), the intermediate
1158		/// types `A` and `B` must implement [`Clone`] because the implementation builds
1159		/// the ternary lift from nested binary `ref_lift2` calls, which requires
1160		/// constructing intermediate tuples.
1161		#[document_signature]
1162		#[document_type_parameters(
1163			"The lifetime.",
1164			"The brand.",
1165			"First type.",
1166			"Second type.",
1167			"Third type.",
1168			"Result type.",
1169			"The first container type (owned or borrowed), inferred from the argument.",
1170			"The second container type (owned or borrowed), inferred from the argument.",
1171			"The third container type (owned or borrowed), inferred from the argument.",
1172			"Dispatch marker."
1173		)]
1174		#[document_parameters(
1175			"The function to lift.",
1176			"First context (owned for Val, borrowed for Ref).",
1177			"Second context (owned for Val, borrowed for Ref).",
1178			"Third context (owned for Val, borrowed for Ref)."
1179		)]
1180		#[document_returns("A new context containing the result.")]
1181		#[document_examples]
1182		///
1183		/// ```
1184		/// use fp_library::{
1185		/// 	brands::*,
1186		/// 	functions::explicit::*,
1187		/// };
1188		/// let r = lift3::<OptionBrand, _, _, _, _, _, _, _, _>(
1189		/// 	|a, b, c| a + b + c,
1190		/// 	Some(1),
1191		/// 	Some(2),
1192		/// 	Some(3),
1193		/// );
1194		/// assert_eq!(r, Some(6));
1195		/// ```
1196		pub fn lift3<
1197			'a,
1198			Brand: Kind_cdc7cd43dac7585f,
1199			A: 'a,
1200			B: 'a,
1201			C: 'a,
1202			D: 'a,
1203			FA,
1204			FB,
1205			FC,
1206			Marker,
1207		>(
1208			f: impl Lift3Dispatch<'a, Brand, A, B, C, D, FA, FB, FC, Marker>,
1209			fa: FA,
1210			fb: FB,
1211			fc: FC,
1212		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) {
1213			f.dispatch(fa, fb, fc)
1214		}
1215
1216		/// Lifts a quaternary function into a functor context.
1217		///
1218		/// When dispatched through the Ref path (`Fn(&A, &B, &C, &D) -> E`), the
1219		/// intermediate types `A`, `B`, and `C` must implement [`Clone`] because
1220		/// the implementation builds the quaternary lift from nested binary
1221		/// `ref_lift2` calls, which requires constructing intermediate tuples.
1222		#[document_signature]
1223		#[document_type_parameters(
1224			"The lifetime.",
1225			"The brand.",
1226			"First.",
1227			"Second.",
1228			"Third.",
1229			"Fourth.",
1230			"Result.",
1231			"The first container type (owned or borrowed), inferred from the argument.",
1232			"The second container type (owned or borrowed), inferred from the argument.",
1233			"The third container type (owned or borrowed), inferred from the argument.",
1234			"The fourth container type (owned or borrowed), inferred from the argument.",
1235			"Dispatch marker."
1236		)]
1237		#[document_parameters(
1238			"The function to lift.",
1239			"First (owned for Val, borrowed for Ref).",
1240			"Second (owned for Val, borrowed for Ref).",
1241			"Third (owned for Val, borrowed for Ref).",
1242			"Fourth (owned for Val, borrowed for Ref)."
1243		)]
1244		#[document_returns("Result context.")]
1245		#[document_examples]
1246		///
1247		/// ```
1248		/// use fp_library::{
1249		/// 	brands::*,
1250		/// 	functions::explicit::*,
1251		/// };
1252		/// let r = lift4::<OptionBrand, _, _, _, _, _, _, _, _, _, _>(
1253		/// 	|a, b, c, d| a + b + c + d,
1254		/// 	Some(1),
1255		/// 	Some(2),
1256		/// 	Some(3),
1257		/// 	Some(4),
1258		/// );
1259		/// assert_eq!(r, Some(10));
1260		/// ```
1261		pub fn lift4<
1262			'a,
1263			Brand: Kind_cdc7cd43dac7585f,
1264			A: 'a,
1265			B: 'a,
1266			C: 'a,
1267			D: 'a,
1268			E: 'a,
1269			FA,
1270			FB,
1271			FC,
1272			FD,
1273			Marker,
1274		>(
1275			f: impl Lift4Dispatch<'a, Brand, A, B, C, D, E, FA, FB, FC, FD, Marker>,
1276			fa: FA,
1277			fb: FB,
1278			fc: FC,
1279			fd: FD,
1280		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>) {
1281			f.dispatch(fa, fb, fc, fd)
1282		}
1283
1284		/// Lifts a quinary function into a functor context.
1285		///
1286		/// When dispatched through the Ref path (`Fn(&A, &B, &C, &D, &E) -> G`),
1287		/// the intermediate types `A`, `B`, `C`, and `D` must implement [`Clone`]
1288		/// because the implementation builds the quinary lift from nested binary
1289		/// `ref_lift2` calls, which requires constructing intermediate tuples.
1290		#[document_signature]
1291		#[document_type_parameters(
1292			"The lifetime.",
1293			"The brand.",
1294			"1st.",
1295			"2nd.",
1296			"3rd.",
1297			"4th.",
1298			"5th.",
1299			"Result.",
1300			"The first container type (owned or borrowed), inferred from the argument.",
1301			"The second container type (owned or borrowed), inferred from the argument.",
1302			"The third container type (owned or borrowed), inferred from the argument.",
1303			"The fourth container type (owned or borrowed), inferred from the argument.",
1304			"The fifth container type (owned or borrowed), inferred from the argument.",
1305			"Dispatch marker."
1306		)]
1307		#[document_parameters(
1308			"The function to lift.",
1309			"1st (owned for Val, borrowed for Ref).",
1310			"2nd (owned for Val, borrowed for Ref).",
1311			"3rd (owned for Val, borrowed for Ref).",
1312			"4th (owned for Val, borrowed for Ref).",
1313			"5th (owned for Val, borrowed for Ref)."
1314		)]
1315		#[document_returns("Result context.")]
1316		#[document_examples]
1317		///
1318		/// ```
1319		/// use fp_library::{
1320		/// 	brands::*,
1321		/// 	functions::explicit::*,
1322		/// };
1323		/// let r = lift5::<OptionBrand, _, _, _, _, _, _, _, _, _, _, _, _>(
1324		/// 	|a, b, c, d, e| a + b + c + d + e,
1325		/// 	Some(1),
1326		/// 	Some(2),
1327		/// 	Some(3),
1328		/// 	Some(4),
1329		/// 	Some(5),
1330		/// );
1331		/// assert_eq!(r, Some(15));
1332		/// ```
1333		pub fn lift5<
1334			'a,
1335			Brand: Kind_cdc7cd43dac7585f,
1336			A: 'a,
1337			B: 'a,
1338			C: 'a,
1339			D: 'a,
1340			E: 'a,
1341			G: 'a,
1342			FA,
1343			FB,
1344			FC,
1345			FD,
1346			FE,
1347			Marker,
1348		>(
1349			f: impl Lift5Dispatch<'a, Brand, A, B, C, D, E, G, FA, FB, FC, FD, FE, Marker>,
1350			fa: FA,
1351			fb: FB,
1352			fc: FC,
1353			fd: FD,
1354			fe: FE,
1355		) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, G>) {
1356			f.dispatch(fa, fb, fc, fd, fe)
1357		}
1358	}
1359}
1360
1361pub use inner::*;