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 cloneable_fn::CloneableFn,
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 #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
36 pub struct Const<'a, R, A>(pub R, pub PhantomData<&'a A>);
37
38 #[document_type_parameters(
39 "The lifetime of the values.",
40 "The stored type.",
41 "The ignored type."
42 )]
43 #[document_parameters("The `Const` instance.")]
44 impl<'a, R, A> Const<'a, R, A> {
45 #[document_signature]
47 #[document_parameters("The value to store.")]
48 #[document_returns("A new `Const` instance.")]
49 #[document_examples]
50 pub fn new(r: R) -> Self {
58 Const(r, PhantomData)
59 }
60
61 #[document_signature]
66 #[document_type_parameters("The new phantom type.")]
67 #[document_parameters("The function to map (ignored).")]
68 #[document_returns(
69 "A new `Const` instance with the same stored value but a different phantom type."
70 )]
71 #[document_examples]
72 pub fn map<B>(
81 self,
82 _f: impl FnOnce(A) -> B,
83 ) -> Const<'a, R, B> {
84 Const::new(self.0)
85 }
86
87 #[document_signature]
91 #[document_type_parameters("The second phantom type.", "The result phantom type.")]
92 #[document_parameters("The other `Const` instance.", "The function to lift (ignored).")]
93 #[document_returns("A new `Const` instance with the appended stored values.")]
94 #[document_examples]
95 pub fn lift2<B, C>(
105 self,
106 other: Const<'a, R, B>,
107 _f: impl FnOnce(A, B) -> C,
108 ) -> Const<'a, R, C>
109 where
110 R: Semigroup, {
111 Const::new(R::append(self.0, other.0))
112 }
113
114 #[document_signature]
118 #[document_type_parameters("The phantom type of the second `Const` instance.")]
119 #[document_parameters("The second `Const` instance.")]
120 #[document_returns("A new `Const` instance with the appended stored values.")]
121 #[document_examples]
122 pub fn apply_first<B>(
132 self,
133 other: Const<'a, R, B>,
134 ) -> Const<'a, R, A>
135 where
136 R: Semigroup, {
137 Const::new(R::append(self.0, other.0))
138 }
139
140 #[document_signature]
144 #[document_type_parameters("The phantom type of the second `Const` instance.")]
145 #[document_parameters("The second `Const` instance.")]
146 #[document_returns("A new `Const` instance with the appended stored values.")]
147 #[document_examples]
148 pub fn apply_second<B>(
158 self,
159 other: Const<'a, R, B>,
160 ) -> Const<'a, R, B>
161 where
162 R: Semigroup, {
163 Const::new(R::append(self.0, other.0))
164 }
165
166 #[document_signature]
170 #[document_parameters("The value to wrap (ignored).")]
171 #[document_returns("A new `Const` instance with the empty value of the stored type.")]
172 #[document_examples]
173 pub fn pure(_a: A) -> Self
181 where
182 R: Monoid, {
183 Const::new(R::empty())
184 }
185 }
186
187 impl_kind! {
188 impl<R: 'static> for ConstBrand<R> {
189 type Of<'a, A: 'a>: 'a = Const<'a, R, A>;
190 }
191 }
192
193 #[document_type_parameters("The stored type.")]
194 impl<R: 'static> Functor for ConstBrand<R> {
195 #[document_signature]
196 #[document_type_parameters(
197 "The lifetime of the values.",
198 "The input type.",
199 "The output type."
200 )]
201 #[document_parameters(
202 "The function to map (ignored).",
203 "The `Const` instance to map over."
204 )]
205 #[document_returns("A new `Const` instance with the same stored value.")]
206 #[document_examples]
207 fn map<'a, A: 'a, B: 'a>(
220 _f: impl Fn(A) -> B + 'a,
221 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
222 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
223 fa.map(_f)
224 }
225 }
226
227 #[document_type_parameters("The stored type.")]
228 impl<R: 'static + Semigroup> Lift for ConstBrand<R> {
229 #[document_signature]
230 #[document_type_parameters(
231 "The lifetime of the values.",
232 "The first input type.",
233 "The second input type.",
234 "The output type."
235 )]
236 #[document_parameters(
237 "The function to lift (ignored).",
238 "The first `Const` instance.",
239 "The second `Const` instance."
240 )]
241 #[document_returns("A new `Const` instance with the combined stored values.")]
242 #[document_examples]
243 fn lift2<'a, A, B, C>(
257 _func: impl Fn(A, B) -> C + 'a,
258 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
259 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
260 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, C>)
261 where
262 A: Clone + 'a,
263 B: Clone + 'a,
264 C: 'a, {
265 fa.lift2(fb, _func)
266 }
267 }
268
269 #[document_type_parameters("The stored type.")]
270 impl<R: 'static + Semigroup> Semiapplicative for ConstBrand<R> {
271 #[document_signature]
272 #[document_type_parameters(
273 "The lifetime of the values.",
274 "The function brand.",
275 "The input type.",
276 "The output type."
277 )]
278 #[document_parameters(
279 "The `Const` instance containing a function.",
280 "The `Const` instance containing a value."
281 )]
282 #[document_returns("A new `Const` instance with the combined stored values.")]
283 #[document_examples]
284 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
304 ff: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
305 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
306 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
307 Const::new(R::append(ff.0, fa.0))
308 }
309 }
310
311 #[document_type_parameters("The stored type.")]
312 impl<R: 'static + Semigroup> ApplyFirst for ConstBrand<R> {
313 #[document_signature]
314 #[document_type_parameters(
315 "The lifetime of the values.",
316 "The first type.",
317 "The second type."
318 )]
319 #[document_parameters("The first `Const` instance.", "The second `Const` instance.")]
320 #[document_returns("A new `Const` instance with the combined stored values.")]
321 #[document_examples]
322 fn apply_first<'a, A: 'a, B: 'a>(
336 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
337 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
338 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>) {
339 fa.apply_first(fb)
340 }
341 }
342
343 #[document_type_parameters("The stored type.")]
344 impl<R: 'static + Semigroup> ApplySecond for ConstBrand<R> {
345 #[document_signature]
346 #[document_type_parameters(
347 "The lifetime of the values.",
348 "The first type.",
349 "The second type."
350 )]
351 #[document_parameters("The first `Const` instance.", "The second `Const` instance.")]
352 #[document_returns("A new `Const` instance with the combined stored values.")]
353 #[document_examples]
354 fn apply_second<'a, A: 'a, B: 'a>(
368 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
369 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
370 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
371 fa.apply_second(fb)
372 }
373 }
374
375 #[document_type_parameters("The stored type.")]
376 impl<R: 'static + Monoid> Pointed for ConstBrand<R> {
377 #[document_signature]
378 #[document_type_parameters("The lifetime of the values.", "The type to wrap (ignored).")]
379 #[document_parameters("The value to wrap (ignored).")]
380 #[document_returns("A new `Const` instance with the empty value of the stored type.")]
381 #[document_examples]
382 fn pure<'a, A: 'a>(_a: A) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>) {
394 Const::pure(_a)
395 }
396 }
397}
398pub use inner::*;
399
400impl<'a, R: Clone, A> Clone for Const<'a, R, A> {
402 fn clone(&self) -> Self {
403 Const(self.0.clone(), std::marker::PhantomData)
404 }
405}
406impl<'a, R: Copy, A> Copy for Const<'a, R, A> {}