1use crate::{
4 brands::{Brand, Brand1},
5 hkt::{Apply, Kind, Kind1},
6 typeclasses::{Apply as TypeclassApply, ApplyFirst, ApplySecond, Bind, Functor, Pure},
7};
8
9pub struct VecBrand;
11
12impl<A> Kind1<A> for VecBrand {
13 type Output = Vec<A>;
14}
15
16impl<A> Brand1<Vec<A>, A> for VecBrand {
17 fn inject(a: Vec<A>) -> Apply<Self, (A,)> {
18 a
19 }
20 fn project(a: Apply<Self, (A,)>) -> Vec<A> {
21 a
22 }
23}
24
25impl Pure for VecBrand {
26 fn pure<A>(a: A) -> Apply<Self, (A,)>
34 where
35 Self: Kind<(A,)>,
36 {
37 <Self as Brand<Vec<A>, (A,)>>::inject(vec![a])
38 }
39}
40
41impl Functor for VecBrand {
42 fn map<F, A, B>(f: F) -> impl Fn(Apply<Self, (A,)>) -> Apply<Self, (B,)>
51 where
52 Self: Kind<(A,)> + Kind<(B,)>,
53 F: Fn(A) -> B,
54 {
55 move |fa| {
56 <Self as Brand<_, (_,)>>::inject(
57 <Self as Brand<_, (_,)>>::project(fa).into_iter().map(&f).collect(),
58 )
59 }
60 }
61}
62
63impl TypeclassApply for VecBrand {
64 fn apply<F, A, B>(ff: Apply<Self, (F,)>) -> impl Fn(Apply<Self, (A,)>) -> Apply<Self, (B,)>
73 where
74 Self: Kind<(F,)> + Kind<(A,)> + Kind<(B,)>,
75 F: Fn(A) -> B,
76 A: Clone,
77 Apply<Self, (F,)>: Clone,
78 {
79 move |fa| {
80 let fa = <Self as Brand<_, (_,)>>::project(fa);
81 <Self as Brand<_, (_,)>>::inject(
82 <Self as Brand<_, (F,)>>::project(ff.to_owned())
83 .into_iter()
84 .flat_map(|f| fa.iter().cloned().map(f))
85 .collect(),
86 )
87 }
88 }
89}
90
91impl ApplyFirst for VecBrand {
92 fn apply_first<A, B>(fa: Apply<Self, (A,)>) -> impl Fn(Apply<Self, (B,)>) -> Apply<Self, (A,)>
102 where
103 Self: Kind<(A,)> + Kind<(B,)>,
104 A: Clone,
105 B: Clone,
106 Apply<Self, (A,)>: Clone,
107 {
108 move |fb| {
109 let fb = <Self as Brand<_, (B,)>>::project(fb);
110 <Self as Brand<_, (_,)>>::inject(
111 <Self as Brand<_, (A,)>>::project(fa.to_owned())
112 .into_iter()
113 .flat_map(|a| fb.iter().cloned().map(move |_b| a.to_owned()))
114 .collect(),
115 )
116 }
117 }
118}
119
120impl ApplySecond for VecBrand {
121 fn apply_second<A, B>(fa: Apply<Self, (A,)>) -> impl Fn(Apply<Self, (B,)>) -> Apply<Self, (B,)>
131 where
132 Self: Kind<(A,)> + Kind<(B,)>,
133 Apply<Self, (A,)>: Clone,
134 B: Clone,
135 {
136 move |fb| {
137 let fb = <Self as Brand<_, (B,)>>::project(fb);
138 <Self as Brand<_, (_,)>>::inject(
139 <Self as Brand<_, (A,)>>::project(fa.to_owned())
140 .into_iter()
141 .flat_map(|_a| fb.iter().cloned())
142 .collect(),
143 )
144 }
145 }
146}
147
148impl Bind for VecBrand {
149 fn bind<F, A, B>(ma: Apply<Self, (A,)>) -> impl Fn(F) -> Apply<Self, (B,)>
158 where
159 Self: Kind<(A,)> + Kind<(B,)> + Sized,
160 F: Fn(A) -> Apply<Self, (B,)>,
161 Apply<Self, (A,)>: Clone,
162 {
163 move |f| {
164 <Self as Brand<_, (_,)>>::inject(
165 <Self as Brand<_, (_,)>>::project(ma.to_owned())
166 .into_iter()
167 .flat_map(|a| <Self as Brand<_, (B,)>>::project(f(a)))
168 .collect(),
169 )
170 }
171 }
172}