1#[fp_macros::document_module]
4mod inner {
5 use {
6 crate::{
7 Apply,
8 brands::ConstBrand,
9 classes::{
10 apply_first::ApplyFirst,
11 apply_second::ApplySecond,
12 clone_fn::CloneFn,
13 functor::Functor,
14 lift::Lift,
15 monoid::Monoid,
16 pointed::Pointed,
17 semiapplicative::Semiapplicative,
18 semigroup::Semigroup,
19 },
20 impl_kind,
21 kinds::*,
22 },
23 fp_macros::*,
24 std::marker::PhantomData,
25 };
26
27 #[document_type_parameters(
31 "The lifetime of the values.",
32 "The stored type.",
33 "The ignored type."
34 )]
35 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36 #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
37 pub struct Const<'a, R, A>(pub R, pub PhantomData<&'a A>);
38
39 #[document_type_parameters(
40 "The lifetime of the values.",
41 "The stored type.",
42 "The ignored type."
43 )]
44 #[document_parameters("The `Const` instance.")]
45 impl<'a, R, A> Const<'a, R, A> {
46 #[document_signature]
48 #[document_parameters("The value to store.")]
49 #[document_returns("A new `Const` instance.")]
50 #[document_examples]
51 pub fn new(r: R) -> Self {
59 Const(r, PhantomData)
60 }
61
62 #[document_signature]
67 #[document_type_parameters("The new phantom type.")]
68 #[document_parameters("The function to map (ignored).")]
69 #[document_returns(
70 "A new `Const` instance with the same stored value but a different phantom type."
71 )]
72 #[document_examples]
73 pub fn map<B>(
82 self,
83 _f: impl FnOnce(A) -> B,
84 ) -> Const<'a, R, B> {
85 Const::new(self.0)
86 }
87
88 #[document_signature]
92 #[document_type_parameters("The second phantom type.", "The result phantom type.")]
93 #[document_parameters("The other `Const` instance.", "The function to lift (ignored).")]
94 #[document_returns("A new `Const` instance with the appended stored values.")]
95 #[document_examples]
96 pub fn lift2<B, C>(
106 self,
107 other: Const<'a, R, B>,
108 _f: impl FnOnce(A, B) -> C,
109 ) -> Const<'a, R, C>
110 where
111 R: Semigroup, {
112 Const::new(R::append(self.0, other.0))
113 }
114
115 #[document_signature]
119 #[document_type_parameters("The phantom type of the second `Const` instance.")]
120 #[document_parameters("The second `Const` instance.")]
121 #[document_returns("A new `Const` instance with the appended stored values.")]
122 #[document_examples]
123 pub fn apply_first<B>(
133 self,
134 other: Const<'a, R, B>,
135 ) -> Const<'a, R, A>
136 where
137 R: Semigroup, {
138 Const::new(R::append(self.0, other.0))
139 }
140
141 #[document_signature]
145 #[document_type_parameters("The phantom type of the second `Const` instance.")]
146 #[document_parameters("The second `Const` instance.")]
147 #[document_returns("A new `Const` instance with the appended stored values.")]
148 #[document_examples]
149 pub fn apply_second<B>(
159 self,
160 other: Const<'a, R, B>,
161 ) -> Const<'a, R, B>
162 where
163 R: Semigroup, {
164 Const::new(R::append(self.0, other.0))
165 }
166
167 #[document_signature]
171 #[document_parameters("The value to wrap (ignored).")]
172 #[document_returns("A new `Const` instance with the empty value of the stored type.")]
173 #[document_examples]
174 pub fn pure(_a: A) -> Self
182 where
183 R: Monoid, {
184 Const::new(R::empty())
185 }
186 }
187
188 impl_kind! {
189 impl<R: 'static> for ConstBrand<R> {
190 type Of<'a, A: 'a>: 'a = Const<'a, R, A>;
191 }
192 }
193
194 #[document_type_parameters("The stored type.")]
195 impl<R: 'static> Functor for ConstBrand<R> {
196 #[document_signature]
197 #[document_type_parameters(
198 "The lifetime of the values.",
199 "The input type.",
200 "The output type."
201 )]
202 #[document_parameters(
203 "The function to map (ignored).",
204 "The `Const` instance to map over."
205 )]
206 #[document_returns("A new `Const` instance with the same stored value.")]
207 #[document_examples]
208 fn map<'a, A: 'a, B: 'a>(
221 _f: impl Fn(A) -> B + 'a,
222 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
223 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
224 fa.map(_f)
225 }
226 }
227
228 #[document_type_parameters("The stored type.")]
229 impl<R: 'static + Semigroup> Lift for ConstBrand<R> {
230 #[document_signature]
231 #[document_type_parameters(
232 "The lifetime of the values.",
233 "The first input type.",
234 "The second input type.",
235 "The output type."
236 )]
237 #[document_parameters(
238 "The function to lift (ignored).",
239 "The first `Const` instance.",
240 "The second `Const` instance."
241 )]
242 #[document_returns("A new `Const` instance with the combined stored values.")]
243 #[document_examples]
244 fn lift2<'a, A, B, C>(
258 _func: impl Fn(A, B) -> C + 'a,
259 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
260 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
261 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, C>)
262 where
263 A: Clone + 'a,
264 B: Clone + 'a,
265 C: 'a, {
266 fa.lift2(fb, _func)
267 }
268 }
269
270 #[document_type_parameters("The stored type.")]
271 impl<R: 'static + Semigroup> Semiapplicative for ConstBrand<R> {
272 #[document_signature]
273 #[document_type_parameters(
274 "The lifetime of the values.",
275 "The function brand.",
276 "The input type.",
277 "The output type."
278 )]
279 #[document_parameters(
280 "The `Const` instance containing a function.",
281 "The `Const` instance containing a value."
282 )]
283 #[document_returns("A new `Const` instance with the combined stored values.")]
284 #[document_examples]
285 fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
305 ff: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
306 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
307 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
308 Const::new(R::append(ff.0, fa.0))
309 }
310 }
311
312 #[document_type_parameters("The stored type.")]
313 impl<R: 'static + Semigroup> ApplyFirst for ConstBrand<R> {
314 #[document_signature]
315 #[document_type_parameters(
316 "The lifetime of the values.",
317 "The first type.",
318 "The second type."
319 )]
320 #[document_parameters("The first `Const` instance.", "The second `Const` instance.")]
321 #[document_returns("A new `Const` instance with the combined stored values.")]
322 #[document_examples]
323 fn apply_first<'a, A: 'a, B: 'a>(
337 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
338 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
339 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>) {
340 fa.apply_first(fb)
341 }
342 }
343
344 #[document_type_parameters("The stored type.")]
345 impl<R: 'static + Semigroup> ApplySecond for ConstBrand<R> {
346 #[document_signature]
347 #[document_type_parameters(
348 "The lifetime of the values.",
349 "The first type.",
350 "The second type."
351 )]
352 #[document_parameters("The first `Const` instance.", "The second `Const` instance.")]
353 #[document_returns("A new `Const` instance with the combined stored values.")]
354 #[document_examples]
355 fn apply_second<'a, A: 'a, B: 'a>(
369 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
370 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
371 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
372 fa.apply_second(fb)
373 }
374 }
375
376 #[document_type_parameters("The stored type.")]
377 impl<R: 'static + Monoid> Pointed for ConstBrand<R> {
378 #[document_signature]
379 #[document_type_parameters("The lifetime of the values.", "The type to wrap (ignored).")]
380 #[document_parameters("The value to wrap (ignored).")]
381 #[document_returns("A new `Const` instance with the empty value of the stored type.")]
382 #[document_examples]
383 fn pure<'a, A: 'a>(_a: A) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>) {
395 Const::pure(_a)
396 }
397 }
398}
399pub use inner::*;
400
401impl<'a, R: Clone, A> Clone for Const<'a, R, A> {
403 fn clone(&self) -> Self {
404 Const(self.0.clone(), std::marker::PhantomData)
405 }
406}
407impl<'a, R: Copy, A> Copy for Const<'a, R, A> {}