1#[fp_macros::document_module]
4mod inner {
5 use {
6 crate::{
7 Apply,
8 classes::{
9 apply_first::ApplyFirst,
10 apply_second::ApplySecond,
11 cloneable_fn::CloneableFn,
12 functor::Functor,
13 lift::Lift,
14 monoid::Monoid,
15 pointed::Pointed,
16 semiapplicative::Semiapplicative,
17 semigroup::Semigroup,
18 },
19 impl_kind,
20 kinds::*,
21 },
22 fp_macros::*,
23 std::marker::PhantomData,
24 };
25
26 #[document_type_parameters(
30 "The lifetime of the values.",
31 "The stored type.",
32 "The ignored type."
33 )]
34 #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
35 pub struct Const<'a, R, A>(pub R, pub PhantomData<&'a A>);
36
37 #[document_type_parameters(
38 "The lifetime of the values.",
39 "The stored type.",
40 "The ignored type."
41 )]
42 impl<'a, R, A> Const<'a, R, A> {
43 #[document_signature]
45 #[document_parameters("The value to store.")]
46 #[document_returns("A new `Const` instance.")]
47 #[document_examples]
48 pub fn new(r: R) -> Self {
56 Const(r, PhantomData)
57 }
58 }
59
60 pub struct ConstBrand<R>(PhantomData<R>);
62
63 impl_kind! {
64 impl<R: 'static> for ConstBrand<R> {
65 type Of<'a, A: 'a>: 'a = Const<'a, R, A>;
66 }
67 }
68
69 #[document_type_parameters("The stored type.")]
70 impl<R: 'static> Functor for ConstBrand<R> {
71 #[document_signature]
72 #[document_type_parameters(
73 "The lifetime of the values.",
74 "The input type.",
75 "The output type."
76 )]
77 #[document_parameters(
78 "The function to map (ignored).",
79 "The `Const` instance to map over."
80 )]
81 #[document_returns("A new `Const` instance with the same stored value.")]
82 #[document_examples]
83 fn map<'a, A: 'a, B: 'a>(
98 _f: impl Fn(A) -> B + 'a,
99 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
100 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
101 Const::new(fa.0)
102 }
103 }
104
105 #[document_type_parameters("The stored type.")]
106 impl<R: 'static + Semigroup> Lift for ConstBrand<R> {
107 #[document_signature]
108 #[document_type_parameters(
109 "The lifetime of the values.",
110 "The first input type.",
111 "The second input type.",
112 "The output type."
113 )]
114 #[document_parameters(
115 "The function to lift (ignored).",
116 "The first `Const` instance.",
117 "The second `Const` instance."
118 )]
119 #[document_returns("A new `Const` instance with the combined stored values.")]
120 #[document_examples]
121 fn lift2<'a, A, B, C>(
137 _func: impl Fn(A, B) -> C + 'a,
138 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
139 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
140 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, C>)
141 where
142 A: Clone + 'a,
143 B: Clone + 'a,
144 C: 'a, {
145 Const::new(R::append(fa.0, fb.0))
146 }
147 }
148
149 #[document_type_parameters("The stored type.")]
150 impl<R: 'static + Semigroup> Semiapplicative for ConstBrand<R> {
151 #[document_signature]
152 #[document_type_parameters(
153 "The lifetime of the values.",
154 "The function brand.",
155 "The input type.",
156 "The output type."
157 )]
158 #[document_parameters(
159 "The `Const` instance containing a function.",
160 "The `Const` instance containing a value."
161 )]
162 #[document_returns("A new `Const` instance with the combined stored values.")]
163 #[document_examples]
164 fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
184 ff: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
185 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
186 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
187 Const::new(R::append(ff.0, fa.0))
188 }
189 }
190
191 #[document_type_parameters("The stored type.")]
192 impl<R: 'static + Semigroup> ApplyFirst for ConstBrand<R> {
193 #[document_signature]
194 #[document_type_parameters(
195 "The lifetime of the values.",
196 "The first type.",
197 "The second type."
198 )]
199 #[document_parameters("The first `Const` instance.", "The second `Const` instance.")]
200 #[document_returns("A new `Const` instance with the combined stored values.")]
201 #[document_examples]
202 fn apply_first<'a, A: 'a, B: 'a>(
218 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
219 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
220 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>) {
221 Const::new(R::append(fa.0, fb.0))
222 }
223 }
224
225 #[document_type_parameters("The stored type.")]
226 impl<R: 'static + Semigroup> ApplySecond for ConstBrand<R> {
227 #[document_signature]
228 #[document_type_parameters(
229 "The lifetime of the values.",
230 "The first type.",
231 "The second type."
232 )]
233 #[document_parameters("The first `Const` instance.", "The second `Const` instance.")]
234 #[document_returns("A new `Const` instance with the combined stored values.")]
235 #[document_examples]
236 fn apply_second<'a, A: 'a, B: 'a>(
252 fa: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>),
253 fb: Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>),
254 ) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, B>) {
255 Const::new(R::append(fa.0, fb.0))
256 }
257 }
258
259 #[document_type_parameters("The stored type.")]
260 impl<R: 'static + Monoid> Pointed for ConstBrand<R> {
261 #[document_signature]
262 #[document_type_parameters("The lifetime of the values.", "The type to wrap (ignored).")]
263 #[document_parameters("The value to wrap (ignored).")]
264 #[document_returns("A new `Const` instance with the empty value of the stored type.")]
265 #[document_examples]
266 fn pure<'a, A: 'a>(_a: A) -> Apply!(<Self as Kind!( type Of<'b, T: 'b>: 'b; )>::Of<'a, A>) {
280 Const::new(R::empty())
281 }
282 }
283}
284pub use inner::*;
285
286impl<'a, R: Clone, A> Clone for Const<'a, R, A> {
288 fn clone(&self) -> Self {
289 Const(self.0.clone(), std::marker::PhantomData)
290 }
291}
292impl<'a, R: Copy, A> Copy for Const<'a, R, A> {}