1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::optics::*,
11 classes::{
12 Profunctor,
13 *,
14 },
15 impl_kind,
16 kinds::*,
17 },
18 fp_macros::*,
19 };
20
21 #[document_type_parameters(
23 "The lifetime of the functions.",
24 "The cloneable function brand.",
25 "The type of the value produced by the forward function.",
26 "The type of the value consumed by the backward function.",
27 "The source type of the structure.",
28 "The target type of the structure."
29 )]
30 pub struct Exchange<'a, FunctionBrand: LiftFn, A: 'a, B: 'a, S: 'a, T: 'a> {
31 pub get: <FunctionBrand as CloneFn>::Of<'a, S, A>,
33 pub set: <FunctionBrand as CloneFn>::Of<'a, B, T>,
35 }
36
37 #[document_type_parameters(
38 "The lifetime of the functions.",
39 "The cloneable function brand.",
40 "The type of the value produced by the forward function.",
41 "The type of the value consumed by the backward function.",
42 "The source type of the structure.",
43 "The target type of the structure."
44 )]
45 impl<'a, FunctionBrand: LiftFn, A: 'a, B: 'a, S: 'a, T: 'a>
46 Exchange<'a, FunctionBrand, A, B, S, T>
47 {
48 #[document_signature]
50 #[document_parameters("The forward function.", "The backward function.")]
52 #[document_returns("A new instance of the type.")]
54 #[document_examples]
56 pub fn new(
72 get: <FunctionBrand as CloneFn>::Of<'a, S, A>,
73 set: <FunctionBrand as CloneFn>::Of<'a, B, T>,
74 ) -> Self {
75 Exchange {
76 get,
77 set,
78 }
79 }
80 }
81
82 impl_kind! {
83 impl<FunctionBrand: LiftFn + 'static, A: 'static, B: 'static> for ExchangeBrand<FunctionBrand, A, B> {
84 #[document_default]
85 type Of<'a, S: 'a, T: 'a>: 'a = Exchange<'a, FunctionBrand, A, B, S, T>;
86 }
87 }
88
89 #[document_type_parameters(
90 "The cloneable function brand.",
91 "The type of the value produced by the forward function.",
92 "The type of the value consumed by the backward function."
93 )]
94 impl<FunctionBrand: LiftFn + 'static, A: 'static, B: 'static> Profunctor
95 for ExchangeBrand<FunctionBrand, A, B>
96 {
97 #[document_signature]
99 #[document_type_parameters(
100 "The lifetime of the functions.",
101 "The source type of the new structure.",
102 "The target type of the new structure.",
103 "The source type of the original structure.",
104 "The target type of the original structure."
105 )]
106 #[document_parameters(
108 "The function to apply to the input.",
109 "The function to apply to the output.",
110 "The exchange instance to transform."
111 )]
112 #[document_returns("A transformed `Exchange` instance.")]
113 #[document_examples]
115 fn dimap<'a, S: 'a, T: 'a, U: 'a, V: 'a>(
145 st: impl Fn(S) -> T + 'a,
146 uv: impl Fn(U) -> V + 'a,
147 puv: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, T, U>),
148 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, V>) {
149 let get = puv.get;
150 let set = puv.set;
151 let st = <FunctionBrand as LiftFn>::new(st);
152 let uv = <FunctionBrand as LiftFn>::new(uv);
153 Exchange::new(
154 <FunctionBrand as LiftFn>::new(move |s: S| (*get)((*st)(s))),
155 <FunctionBrand as LiftFn>::new(move |b: B| (*uv)((*set)(b))),
156 )
157 }
158 }
159}
160pub use inner::*;