1use crate::{
4 classes::{
5 Applicative, ApplyFirst, ApplySecond, ClonableFn, Foldable, Functor, Pointed,
6 Semiapplicative, Semimonad, Traversable, clonable_fn::ApplyFn,
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: ApplyFn<'a, ClonableFnBrand, A, B>
36 ) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, Apply0L1T<Self, B>> {
37 ClonableFnBrand::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, ApplyFn<'a, ClonableFnBrand, A, B>>
55 ) -> ApplyFn<'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 ) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, A>> {
75 ClonableFnBrand::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 ) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, B>> {
94 ClonableFnBrand::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 ) -> ApplyFn<
129 'a,
130 ClonableFnBrand,
131 ApplyFn<'a, ClonableFnBrand, A, Apply0L1T<Self, B>>,
132 Apply0L1T<Self, B>,
133 > {
134 ClonableFnBrand::new(move |f: ApplyFn<'a, ClonableFnBrand, _, _>| f(ma.to_owned().0))
135 }
136}
137
138impl Foldable for IdentityBrand {
139 fn fold_right<'a, ClonableFnBrand: 'a + ClonableFn, A: Clone, B: Clone>(
155 f: ApplyFn<'a, ClonableFnBrand, A, ApplyFn<'a, ClonableFnBrand, B, B>>
156 ) -> ApplyFn<'a, ClonableFnBrand, B, ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, B>> {
157 ClonableFnBrand::new(move |b: B| {
158 ClonableFnBrand::new({
159 let f = f.clone();
160 move |fa: Apply0L1T<Self, _>| f(fa.0)(b.to_owned())
161 })
162 })
163 }
164}
165
166impl Traversable for IdentityBrand {
167 fn traverse<'a, ClonableFnBrand: 'a + ClonableFn, F: Applicative, A: Clone, B: 'a + Clone>(
183 f: ApplyFn<'a, ClonableFnBrand, A, Apply0L1T<F, B>>
184 ) -> ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, A>, Apply0L1T<F, Apply0L1T<Self, B>>>
185 where
186 Apply0L1T<F, B>: Clone,
187 Apply0L1T<F, ApplyFn<'a, ClonableFnBrand, Apply0L1T<Self, B>, Apply0L1T<Self, B>>>: Clone,
188 Apply0L1T<Self, B>: 'a,
189 Apply0L1T<Self, Apply0L1T<F, B>>: 'a,
190 {
191 ClonableFnBrand::new(move |ta: Apply0L1T<Self, _>| {
192 map::<ClonableFnBrand, F, B, _>(ClonableFnBrand::new(pure::<ClonableFnBrand, Self, _>))(
193 f(ta.0),
194 )
195 })
196 }
197}