Skip to main content

fp_library/classes/
ref_bitraversable.rs

1//! By-reference traversal of bifunctor structures.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{
7//! 	brands::*,
8//! 	functions::explicit::*,
9//! };
10//!
11//! let x: Result<i32, i32> = Ok(5);
12//! let y = bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>(
13//! 	(|e: &i32| Some(e + 1), |s: &i32| Some(s * 2)),
14//! 	&x,
15//! );
16//! assert_eq!(y, Some(Ok(10)));
17//! ```
18
19#[fp_macros::document_module]
20mod inner {
21	use {
22		crate::{
23			classes::*,
24			kinds::*,
25		},
26		fp_macros::*,
27	};
28
29	/// A type class for data structures with two type arguments that can be traversed by reference.
30	///
31	/// Similar to [`Bitraversable`], but closures receive `&A` and `&B` instead of owned values.
32	/// This enables traversing bifunctor structures by reference without consuming elements.
33	///
34	/// ### Minimal Implementation
35	///
36	/// A minimal implementation requires [`RefBitraversable::ref_bi_traverse`] to be defined directly.
37	/// [`RefBitraversable::ref_bi_sequence`] is derived from it via `Clone::clone`.
38	///
39	/// Note: defining both defaults creates a circular dependency and will not terminate.
40	///
41	/// ### Laws
42	///
43	/// `RefBitraversable` instances must be consistent with `RefBifunctor` and `RefBifoldable`:
44	/// * Traverse/sequence consistency: `ref_bi_traverse(f, g, x) = ref_bi_sequence(ref_bimap(f, g, x))`.
45	#[document_examples]
46	///
47	/// RefBitraversable laws for [`Result`]:
48	///
49	/// ```
50	/// use fp_library::{
51	/// 	brands::*,
52	/// 	functions::{
53	/// 		explicit::{
54	/// 			bi_traverse,
55	/// 			bimap,
56	/// 		},
57	/// 		*,
58	/// 	},
59	/// };
60	///
61	/// // ResultBrand has Of<E, A> = Result<A, E>, so the first function handles errors
62	/// // and the second function handles ok values.
63	/// let f = |e: &String| if e.is_empty() { None } else { Some(e.len()) };
64	/// let g = |a: &i32| if *a > 0 { Some(a * 2) } else { None };
65	///
66	/// // Traverse/sequence consistency (Ok case):
67	/// // bi_traverse((f, g), &x) = ref_bi_sequence(&bimap((f, g), &x))
68	/// let ok: Result<i32, String> = Ok(5);
69	/// assert_eq!(
70	/// 	bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>((&f, &g), &ok),
71	/// 	ref_bi_sequence::<ResultBrand, RcFnBrand, _, _, OptionBrand>(&bimap::<
72	/// 		ResultBrand,
73	/// 		_,
74	/// 		_,
75	/// 		_,
76	/// 		_,
77	/// 		_,
78	/// 		_,
79	/// 	>((&f, &g), &ok),),
80	/// );
81	///
82	/// // Traverse/sequence consistency (Err case):
83	/// let err: Result<i32, String> = Err("hello".to_string());
84	/// assert_eq!(
85	/// 	bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>((&f, &g), &err),
86	/// 	ref_bi_sequence::<ResultBrand, RcFnBrand, _, _, OptionBrand>(&bimap::<
87	/// 		ResultBrand,
88	/// 		_,
89	/// 		_,
90	/// 		_,
91	/// 		_,
92	/// 		_,
93	/// 		_,
94	/// 	>((&f, &g), &err),),
95	/// );
96	/// ```
97	#[kind(type Of<'a, A: 'a, B: 'a>: 'a;)]
98	pub trait RefBitraversable: RefBifunctor + RefBifoldable {
99		/// Traverses the bitraversable structure by reference with two effectful functions.
100		///
101		/// This method applies `f` to references of first-position values and `g` to references
102		/// of second-position values, accumulating all effects in the applicative context `F`.
103		#[document_signature]
104		///
105		#[document_type_parameters(
106			"The lifetime of the values.",
107			"The brand of the cloneable function wrapper.",
108			"The type of the first-position elements.",
109			"The type of the second-position elements.",
110			"The output type for first-position elements.",
111			"The output type for second-position elements.",
112			"The applicative context."
113		)]
114		///
115		#[document_parameters(
116			"The function for first-position element references.",
117			"The function for second-position element references.",
118			"The bitraversable structure to traverse by reference."
119		)]
120		///
121		#[document_returns("The transformed structure wrapped in the applicative context.")]
122		#[document_examples]
123		///
124		/// ```
125		/// use fp_library::{
126		/// 	brands::*,
127		/// 	functions::explicit::*,
128		/// };
129		///
130		/// let x: Result<i32, i32> = Err(3);
131		/// let y = bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>(
132		/// 	(|e: &i32| Some(e + 1), |s: &i32| Some(s * 2)),
133		/// 	&x,
134		/// );
135		/// assert_eq!(y, Some(Err(4)));
136		/// ```
137		fn ref_bi_traverse<
138			'a,
139			FnBrand,
140			A: 'a + Clone,
141			B: 'a + Clone,
142			C: 'a + Clone,
143			D: 'a + Clone,
144			F: Applicative,
145		>(
146			f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
147			g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
148			p: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
149		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>)>)
150		where
151			FnBrand: LiftFn + 'a,
152			Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>): Clone,
153			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
154			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone;
155
156		/// Sequences a bitraversable structure containing applicative values by reference.
157		///
158		/// Collapses a structure of effectful values into a single effectful structure,
159		/// cloning each element via [`Clone::clone`] through [`RefBitraversable::ref_bi_traverse`].
160		#[document_signature]
161		///
162		#[document_type_parameters(
163			"The lifetime of the values.",
164			"The brand of the cloneable function wrapper.",
165			"The type of the first-position elements.",
166			"The type of the second-position elements.",
167			"The applicative context."
168		)]
169		///
170		#[document_parameters("The bitraversable structure containing applicative values.")]
171		///
172		#[document_returns("The applicative context wrapping the bitraversable structure.")]
173		#[document_examples]
174		///
175		/// ```
176		/// use fp_library::{
177		/// 	brands::*,
178		/// 	functions::*,
179		/// };
180		///
181		/// let x: Result<Option<i32>, Option<i32>> = Ok(Some(5));
182		/// let y = ref_bi_sequence::<ResultBrand, RcFnBrand, _, _, OptionBrand>(&x);
183		/// assert_eq!(y, Some(Ok(5)));
184		/// ```
185		fn ref_bi_sequence<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
186			ta: &Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>), Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
187		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>)>)
188		where
189			FnBrand: LiftFn + 'a,
190			Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>): Clone,
191			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
192			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
193			Self::ref_bi_traverse::<
194				FnBrand,
195				Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
196				Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
197				A,
198				B,
199				F,
200			>(Clone::clone, Clone::clone, ta)
201		}
202	}
203
204	/// Traverses a bitraversable structure by reference with two effectful functions.
205	///
206	/// Free function version that dispatches to [the type class' associated function][`RefBitraversable::ref_bi_traverse`].
207	#[document_signature]
208	///
209	#[document_type_parameters(
210		"The lifetime of the values.",
211		"The brand of the bitraversable structure.",
212		"The brand of the cloneable function wrapper.",
213		"The type of the first-position elements.",
214		"The type of the second-position elements.",
215		"The output type for first-position elements.",
216		"The output type for second-position elements.",
217		"The applicative context."
218	)]
219	///
220	#[document_parameters(
221		"The function for first-position element references.",
222		"The function for second-position element references.",
223		"The bitraversable structure to traverse by reference."
224	)]
225	///
226	#[document_returns("The transformed structure wrapped in the applicative context.")]
227	#[document_examples]
228	///
229	/// ```
230	/// use fp_library::{
231	/// 	brands::*,
232	/// 	functions::explicit::*,
233	/// };
234	///
235	/// let x: Result<i32, i32> = Ok(5);
236	/// let y = bi_traverse::<RcFnBrand, ResultBrand, _, _, _, _, OptionBrand, _, _>(
237	/// 	(|e: &i32| Some(e + 1), |s: &i32| Some(s * 2)),
238	/// 	&x,
239	/// );
240	/// assert_eq!(y, Some(Ok(10)));
241	/// ```
242	pub fn ref_bi_traverse<
243		'a,
244		Brand: RefBitraversable,
245		FnBrand,
246		A: 'a + Clone,
247		B: 'a + Clone,
248		C: 'a + Clone,
249		D: 'a + Clone,
250		F: Applicative,
251	>(
252		f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
253		g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
254		p: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
255	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>)>)
256	where
257		FnBrand: LiftFn + 'a,
258		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>): Clone,
259		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
260		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone, {
261		Brand::ref_bi_traverse::<FnBrand, A, B, C, D, F>(f, g, p)
262	}
263
264	/// Sequences a bitraversable structure containing applicative values by reference.
265	///
266	/// Free function version that dispatches to [the type class' associated function][`RefBitraversable::ref_bi_sequence`].
267	#[document_signature]
268	///
269	#[document_type_parameters(
270		"The lifetime of the values.",
271		"The brand of the bitraversable structure.",
272		"The brand of the cloneable function wrapper.",
273		"The type of the first-position elements.",
274		"The type of the second-position elements.",
275		"The applicative context."
276	)]
277	///
278	#[document_parameters("The bitraversable structure containing applicative values.")]
279	///
280	#[document_returns("The applicative context wrapping the bitraversable structure.")]
281	#[document_examples]
282	///
283	/// ```
284	/// use fp_library::{
285	/// 	brands::*,
286	/// 	functions::*,
287	/// };
288	///
289	/// let x: Result<Option<i32>, Option<i32>> = Ok(Some(5));
290	/// let y = ref_bi_sequence::<ResultBrand, RcFnBrand, _, _, OptionBrand>(&x);
291	/// assert_eq!(y, Some(Ok(5)));
292	/// ```
293	pub fn ref_bi_sequence<
294		'a,
295		Brand: RefBitraversable,
296		FnBrand,
297		A: 'a + Clone,
298		B: 'a + Clone,
299		F: Applicative,
300	>(
301		ta: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>), Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
302	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>)>)
303	where
304		FnBrand: LiftFn + 'a,
305		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>): Clone,
306		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
307		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
308		Brand::ref_bi_sequence::<FnBrand, A, B, F>(ta)
309	}
310
311	/// Traverses only the first-position elements by reference, lifting second-position elements via `pure`.
312	///
313	/// Equivalent to `ref_bi_traverse(f, |b| F::pure(b.clone()), p)`.
314	#[document_signature]
315	///
316	#[document_type_parameters(
317		"The lifetime of the values.",
318		"The brand of the bitraversable structure.",
319		"The brand of the cloneable function wrapper.",
320		"The type of the first-position elements.",
321		"The type of the second-position elements (unchanged).",
322		"The output type for first-position elements.",
323		"The applicative context."
324	)]
325	///
326	#[document_parameters(
327		"The function for first-position element references.",
328		"The bitraversable structure to traverse by reference."
329	)]
330	///
331	#[document_returns("The transformed structure wrapped in the applicative context.")]
332	#[document_examples]
333	///
334	/// ```
335	/// use fp_library::{
336	/// 	brands::*,
337	/// 	functions::*,
338	/// };
339	///
340	/// let x: Result<i32, i32> = Err(3);
341	/// let y = ref_bi_traverse_left::<ResultBrand, RcFnBrand, _, _, _, OptionBrand>(
342	/// 	|e: &i32| Some(e + 1),
343	/// 	&x,
344	/// );
345	/// assert_eq!(y, Some(Err(4)));
346	/// ```
347	pub fn ref_bi_traverse_left<
348		'a,
349		Brand: RefBitraversable,
350		FnBrand,
351		A: 'a + Clone,
352		B: 'a + Clone,
353		C: 'a + Clone,
354		F: Applicative,
355	>(
356		f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
357		p: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
358	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, B>)>)
359	where
360		FnBrand: LiftFn + 'a,
361		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, B>): Clone,
362		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
363		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
364		Brand::ref_bi_traverse::<FnBrand, A, B, C, B, F>(f, |b: &B| F::pure(b.clone()), p)
365	}
366
367	/// Traverses only the second-position elements by reference, lifting first-position elements via `pure`.
368	///
369	/// Equivalent to `ref_bi_traverse(|a| F::pure(a.clone()), g, p)`.
370	#[document_signature]
371	///
372	#[document_type_parameters(
373		"The lifetime of the values.",
374		"The brand of the bitraversable structure.",
375		"The brand of the cloneable function wrapper.",
376		"The type of the first-position elements (unchanged).",
377		"The type of the second-position elements.",
378		"The output type for second-position elements.",
379		"The applicative context."
380	)]
381	///
382	#[document_parameters(
383		"The function for second-position element references.",
384		"The bitraversable structure to traverse by reference."
385	)]
386	///
387	#[document_returns("The transformed structure wrapped in the applicative context.")]
388	#[document_examples]
389	///
390	/// ```
391	/// use fp_library::{
392	/// 	brands::*,
393	/// 	functions::*,
394	/// };
395	///
396	/// let x: Result<i32, i32> = Ok(5);
397	/// let y = ref_bi_traverse_right::<ResultBrand, RcFnBrand, _, _, _, OptionBrand>(
398	/// 	|s: &i32| Some(s * 2),
399	/// 	&x,
400	/// );
401	/// assert_eq!(y, Some(Ok(10)));
402	/// ```
403	pub fn ref_bi_traverse_right<
404		'a,
405		Brand: RefBitraversable,
406		FnBrand,
407		A: 'a + Clone,
408		B: 'a + Clone,
409		D: 'a + Clone,
410		F: Applicative,
411	>(
412		g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
413		p: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
414	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, D>)>)
415	where
416		FnBrand: LiftFn + 'a,
417		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, D>): Clone,
418		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
419		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone, {
420		Brand::ref_bi_traverse::<FnBrand, A, B, A, D, F>(|a: &A| F::pure(a.clone()), g, p)
421	}
422
423	/// Traverses the bitraversable structure by reference with arguments flipped.
424	///
425	/// Equivalent to `ref_bi_traverse(f, g, p)` with the structure argument first.
426	#[document_signature]
427	///
428	#[document_type_parameters(
429		"The lifetime of the values.",
430		"The brand of the bitraversable structure.",
431		"The brand of the cloneable function wrapper.",
432		"The type of the first-position elements.",
433		"The type of the second-position elements.",
434		"The output type for first-position elements.",
435		"The output type for second-position elements.",
436		"The applicative context."
437	)]
438	///
439	#[document_parameters(
440		"The bitraversable structure to traverse by reference.",
441		"The function for first-position element references.",
442		"The function for second-position element references."
443	)]
444	///
445	#[document_returns("The transformed structure wrapped in the applicative context.")]
446	#[document_examples]
447	///
448	/// ```
449	/// use fp_library::{
450	/// 	brands::*,
451	/// 	functions::*,
452	/// };
453	///
454	/// let x: Result<i32, i32> = Ok(5);
455	/// let y = ref_bi_for::<ResultBrand, RcFnBrand, _, _, _, _, OptionBrand>(
456	/// 	&x,
457	/// 	|e: &i32| Some(e + 1),
458	/// 	|s: &i32| Some(s * 2),
459	/// );
460	/// assert_eq!(y, Some(Ok(10)));
461	/// ```
462	pub fn ref_bi_for<
463		'a,
464		Brand: RefBitraversable,
465		FnBrand,
466		A: 'a + Clone,
467		B: 'a + Clone,
468		C: 'a + Clone,
469		D: 'a + Clone,
470		F: Applicative,
471	>(
472		p: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
473		f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
474		g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
475	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>)>)
476	where
477		FnBrand: LiftFn + 'a,
478		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>): Clone,
479		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
480		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone, {
481		Brand::ref_bi_traverse::<FnBrand, A, B, C, D, F>(f, g, p)
482	}
483
484	/// Traverses only the first-position elements by reference with arguments flipped.
485	///
486	/// Equivalent to `ref_bi_traverse_left(f, p)` with the structure argument first.
487	#[document_signature]
488	///
489	#[document_type_parameters(
490		"The lifetime of the values.",
491		"The brand of the bitraversable structure.",
492		"The brand of the cloneable function wrapper.",
493		"The type of the first-position elements.",
494		"The type of the second-position elements (unchanged).",
495		"The output type for first-position elements.",
496		"The applicative context."
497	)]
498	///
499	#[document_parameters(
500		"The bitraversable structure to traverse by reference.",
501		"The function for first-position element references."
502	)]
503	///
504	#[document_returns("The transformed structure wrapped in the applicative context.")]
505	#[document_examples]
506	///
507	/// ```
508	/// use fp_library::{
509	/// 	brands::*,
510	/// 	functions::*,
511	/// };
512	///
513	/// let x: Result<i32, i32> = Err(3);
514	/// let y =
515	/// 	ref_bi_for_left::<ResultBrand, RcFnBrand, _, _, _, OptionBrand>(&x, |e: &i32| Some(e + 1));
516	/// assert_eq!(y, Some(Err(4)));
517	/// ```
518	pub fn ref_bi_for_left<
519		'a,
520		Brand: RefBitraversable,
521		FnBrand,
522		A: 'a + Clone,
523		B: 'a + Clone,
524		C: 'a + Clone,
525		F: Applicative,
526	>(
527		p: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
528		f: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
529	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, B>)>)
530	where
531		FnBrand: LiftFn + 'a,
532		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, B>): Clone,
533		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>): Clone,
534		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
535		Brand::ref_bi_traverse::<FnBrand, A, B, C, B, F>(f, |b: &B| F::pure(b.clone()), p)
536	}
537
538	/// Traverses only the second-position elements by reference with arguments flipped.
539	///
540	/// Equivalent to `ref_bi_traverse_right(g, p)` with the structure argument first.
541	#[document_signature]
542	///
543	#[document_type_parameters(
544		"The lifetime of the values.",
545		"The brand of the bitraversable structure.",
546		"The brand of the cloneable function wrapper.",
547		"The type of the first-position elements (unchanged).",
548		"The type of the second-position elements.",
549		"The output type for second-position elements.",
550		"The applicative context."
551	)]
552	///
553	#[document_parameters(
554		"The bitraversable structure to traverse by reference.",
555		"The function for second-position element references."
556	)]
557	///
558	#[document_returns("The transformed structure wrapped in the applicative context.")]
559	#[document_examples]
560	///
561	/// ```
562	/// use fp_library::{
563	/// 	brands::*,
564	/// 	functions::*,
565	/// };
566	///
567	/// let x: Result<i32, i32> = Ok(5);
568	/// let y =
569	/// 	ref_bi_for_right::<ResultBrand, RcFnBrand, _, _, _, OptionBrand>(&x, |s: &i32| Some(s * 2));
570	/// assert_eq!(y, Some(Ok(10)));
571	/// ```
572	pub fn ref_bi_for_right<
573		'a,
574		Brand: RefBitraversable,
575		FnBrand,
576		A: 'a + Clone,
577		B: 'a + Clone,
578		D: 'a + Clone,
579		F: Applicative,
580	>(
581		p: &Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
582		g: impl Fn(&B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
583	) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, D>)>)
584	where
585		FnBrand: LiftFn + 'a,
586		Apply!(<Brand as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, D>): Clone,
587		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
588		Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>): Clone, {
589		Brand::ref_bi_traverse::<FnBrand, A, B, A, D, F>(|a: &A| F::pure(a.clone()), g, p)
590	}
591}
592
593pub use inner::*;