1#[fp_macros::document_module]
7mod inner {
8 use {
9 crate::{
10 Apply,
11 brands::optics::*,
12 classes::{
13 profunctor::{
14 Closed,
15 Profunctor,
16 },
17 *,
18 },
19 impl_kind,
20 kinds::*,
21 },
22 fp_macros::*,
23 };
24
25 #[document_type_parameters(
34 "The lifetime of the function.",
35 "The cloneable function brand.",
36 "The input type (contravariant).",
37 "The output type (covariant)."
38 )]
39 pub struct Zipping<'a, FunctionBrand: LiftFn, S: 'a, T: 'a> {
40 pub run: <FunctionBrand as CloneFn>::Of<'a, (S, S), T>,
42 }
43
44 #[document_type_parameters(
45 "The lifetime of the function.",
46 "The cloneable function brand.",
47 "The input type.",
48 "The output type."
49 )]
50 impl<'a, FunctionBrand: LiftFn, S: 'a, T: 'a> Zipping<'a, FunctionBrand, S, T> {
51 #[document_signature]
53 #[document_parameters(
55 "The binary function to wrap, taking a pair `(S, S)` and returning `T`."
56 )]
57 #[document_returns("A new instance of the type.")]
59 #[document_examples]
60 pub fn new(f: impl Fn((S, S)) -> T + 'a) -> Self {
71 Zipping {
72 run: <FunctionBrand as LiftFn>::new(f),
73 }
74 }
75 }
76
77 #[document_type_parameters(
78 "The lifetime of the function.",
79 "The cloneable function brand.",
80 "The input type.",
81 "The output type."
82 )]
83 #[document_parameters("The zipping instance.")]
84 impl<'a, FunctionBrand: LiftFn, S: 'a, T: 'a> Clone for Zipping<'a, FunctionBrand, S, T> {
85 #[document_signature]
86 #[document_returns("A new `Zipping` instance that is a copy of the original.")]
87 #[document_examples]
88 fn clone(&self) -> Self {
100 Zipping {
101 run: self.run.clone(),
102 }
103 }
104 }
105
106 impl_kind! {
107 impl<FunctionBrand: LiftFn + 'static> for ZippingBrand<FunctionBrand> {
108 #[document_default]
109 type Of<'a, S: 'a, T: 'a>: 'a = Zipping<'a, FunctionBrand, S, T>;
110 }
111 }
112
113 #[document_type_parameters("The cloneable function brand.")]
114 impl<FunctionBrand: LiftFn + 'static> Profunctor for ZippingBrand<FunctionBrand> {
115 #[document_signature]
119 #[document_type_parameters(
120 "The lifetime of the values.",
121 "The new input type.",
122 "The original input type.",
123 "The original output type.",
124 "The new output type."
125 )]
126 #[document_parameters(
128 "The contravariant function to pre-compose on both inputs.",
129 "The covariant function to post-compose on the output.",
130 "The zipping instance to transform."
131 )]
132 #[document_returns("A transformed `Zipping` instance.")]
133 #[document_examples]
135 fn dimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
152 ab: impl Fn(A) -> B + 'a,
153 cd: impl Fn(C) -> D + 'a,
154 pbc: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, B, C>),
155 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, A, D>) {
156 Zipping::new(move |(a1, a2)| cd((*pbc.run)((ab(a1), ab(a2)))))
157 }
158 }
159
160 #[document_type_parameters("The cloneable function brand.")]
161 impl<FunctionBrand: LiftFn + 'static> Closed<FunctionBrand> for ZippingBrand<FunctionBrand> {
162 #[document_signature]
171 #[document_type_parameters(
172 "The lifetime of the values.",
173 "The source type of the profunctor.",
174 "The target type of the profunctor.",
175 "The shared input type for the lifted functions."
176 )]
177 #[document_parameters("The zipping instance to lift.")]
179 #[document_returns("A transformed `Zipping` instance that operates on functions.")]
180 #[document_examples]
182 fn closed<'a, S: 'a, T: 'a, X: 'a + Clone>(
208 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
209 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, <FunctionBrand as CloneFn>::Of<'a, X, S>, <FunctionBrand as CloneFn>::Of<'a, X, T>>)
210 {
211 Zipping::new(
212 move |(f1, f2): (
213 <FunctionBrand as CloneFn>::Of<'a, X, S>,
214 <FunctionBrand as CloneFn>::Of<'a, X, S>,
215 )| {
216 let run = pab.run.clone();
217 <FunctionBrand as LiftFn>::new(move |x: X| {
218 (*run)((f1(x.clone()), f2(x.clone())))
219 })
220 },
221 )
222 }
223 }
224}
225pub use inner::*;