1use crate::{
4 classes::{
5 Applicative, ApplyFirst, ApplySecond, ClonableFn, Foldable, Functor, Pointed,
6 Semiapplicative, Semimonad, Traversable, clonable_fn::ApplyClonableFn,
7 },
8 functions::{identity, map, pure},
9 hkt::{Apply0L1T, Kind0L1T},
10};
11
12#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
14pub struct Identity<A>(pub A);
15
16pub struct IdentityBrand;
17
18impl Kind0L1T for IdentityBrand {
19 type Output<A> = Identity<A>;
20}
21
22impl Functor for IdentityBrand {
23 fn map<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a, B: 'a>(
35 f: ApplyClonableFn<'a, ClonableFnBrand, A, B>
36 ) -> ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, Apply0L1T<Self, B>> {
37 <ClonableFnBrand as ClonableFn>::new(move |fa: Apply0L1T<Self, _>| Identity(f(fa.0)))
38 }
39}
40
41impl Semiapplicative for IdentityBrand {
42 fn apply<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a + Clone, B: 'a>(
54 ff: Apply0L1T<Self, ApplyClonableFn<'a, ClonableFnBrand, A, B>>
55 ) -> ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, Apply0L1T<Self, B>> {
56 map::<ClonableFnBrand, Self, A, B>(ff.0)
57 }
58}
59
60impl ApplyFirst for IdentityBrand {
61 fn apply_first<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a + Clone, B: Clone>(
73 fa: Apply0L1T<Self, A>
74 ) -> ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, A>> {
75 <ClonableFnBrand as ClonableFn>::new(move |_fb| fa.to_owned())
76 }
77}
78
79impl ApplySecond for IdentityBrand {
80 fn apply_second<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a + Clone, B: 'a + Clone>(
92 _fa: Apply0L1T<Self, A>
93 ) -> ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, B>> {
94 <ClonableFnBrand as ClonableFn>::new(identity)
95 }
96}
97
98impl Pointed for IdentityBrand {
99 fn pure<ClonableFnBrand: ClonableFn, A: Clone>(a: A) -> Apply0L1T<Self, A> {
110 Identity(a)
111 }
112}
113
114impl Semimonad for IdentityBrand {
115 fn bind<'a, ClonableFnBrand: 'a + ClonableFn, A: 'a + Clone, B: Clone>(
127 ma: Apply0L1T<Self, A>
128 ) -> ApplyClonableFn<
129 'a,
130 ClonableFnBrand,
131 ApplyClonableFn<'a, ClonableFnBrand, A, Apply0L1T<Self, B>>,
132 Apply0L1T<Self, B>,
133 > {
134 <ClonableFnBrand as ClonableFn>::new(
135 move |f: ApplyClonableFn<'a, ClonableFnBrand, _, _>| f(ma.to_owned().0),
136 )
137 }
138}
139
140impl Foldable for IdentityBrand {
141 fn fold_right<'a, ClonableFnBrand: 'a + ClonableFn, A: Clone, B: Clone>(
157 f: ApplyClonableFn<'a, ClonableFnBrand, A, ApplyClonableFn<'a, ClonableFnBrand, B, B>>
158 ) -> ApplyClonableFn<
159 'a,
160 ClonableFnBrand,
161 B,
162 ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, B>,
163 > {
164 <ClonableFnBrand as ClonableFn>::new(move |b: B| {
165 <ClonableFnBrand as ClonableFn>::new({
166 let f = f.clone();
167 move |fa: Apply0L1T<Self, _>| f(fa.0)(b.to_owned())
168 })
169 })
170 }
171}
172
173impl Traversable for IdentityBrand {
174 fn traverse<'a, ClonableFnBrand: 'a + ClonableFn, F: Applicative, A: Clone, B: 'a + Clone>(
190 f: ApplyClonableFn<'a, ClonableFnBrand, A, Apply0L1T<F, B>>
191 ) -> ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, Apply0L1T<F, Apply0L1T<Self, B>>>
192 where
193 Apply0L1T<F, B>: Clone,
194 Apply0L1T<F, ApplyClonableFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, B>>>:
195 Clone,
196 Apply0L1T<Self, B>: 'a,
197 Apply0L1T<Self, Apply0L1T<F, B>>: 'a,
198 {
199 <ClonableFnBrand as ClonableFn>::new(move |ta: Apply0L1T<Self, _>| {
200 map::<ClonableFnBrand, F, B, _>(<ClonableFnBrand as ClonableFn>::new(
201 pure::<ClonableFnBrand, Self, _>,
202 ))(f(ta.0))
203 })
204 }
205}