1use crate::{
4 hkt::{Apply, Brand, Brand1, Kind, Kind1},
5 impl_brand,
6 typeclasses::{Apply as TypeclassApply, ApplyFirst, ApplySecond, Bind, Functor, Pure},
7};
8
9pub mod concrete_vec;
10
11pub use concrete_vec::*;
12
13impl_brand!(VecBrand, Vec, Kind1, Brand1, (A));
14
15impl Pure for VecBrand {
16 fn pure<A>(a: A) -> Apply<Self, (A,)>
24 where
25 Self: Kind<(A,)>,
26 {
27 <Self as Brand<Vec<A>, (A,)>>::inject(vec![a])
28 }
29}
30
31impl Functor for VecBrand {
32 fn map<F, A, B>(f: F) -> impl Fn(Apply<Self, (A,)>) -> Apply<Self, (B,)>
41 where
42 Self: Kind<(A,)> + Kind<(B,)>,
43 F: Fn(A) -> B,
44 {
45 move |fa| {
46 <Self as Brand<_, (_,)>>::inject(
47 <Self as Brand<_, (_,)>>::project(fa).into_iter().map(&f).collect(),
48 )
49 }
50 }
51}
52
53impl TypeclassApply for VecBrand {
54 fn apply<F, A, B>(ff: Apply<Self, (F,)>) -> impl Fn(Apply<Self, (A,)>) -> Apply<Self, (B,)>
63 where
64 Self: Kind<(F,)> + Kind<(A,)> + Kind<(B,)>,
65 F: Fn(A) -> B,
66 A: Clone,
67 Apply<Self, (F,)>: Clone,
68 {
69 move |fa| {
70 let fa = <Self as Brand<_, (_,)>>::project(fa);
71 <Self as Brand<_, (_,)>>::inject(
72 <Self as Brand<_, (F,)>>::project(ff.to_owned())
73 .into_iter()
74 .flat_map(|f| fa.iter().cloned().map(f))
75 .collect(),
76 )
77 }
78 }
79}
80
81impl ApplyFirst for VecBrand {
82 fn apply_first<A, B>(fa: Apply<Self, (A,)>) -> impl Fn(Apply<Self, (B,)>) -> Apply<Self, (A,)>
92 where
93 Self: Kind<(A,)> + Kind<(B,)>,
94 A: Clone,
95 B: Clone,
96 Apply<Self, (A,)>: Clone,
97 {
98 move |fb| {
99 let fb = <Self as Brand<_, (B,)>>::project(fb);
100 <Self as Brand<_, (_,)>>::inject(
101 <Self as Brand<_, (A,)>>::project(fa.to_owned())
102 .into_iter()
103 .flat_map(|a| fb.iter().cloned().map(move |_b| a.to_owned()))
104 .collect(),
105 )
106 }
107 }
108}
109
110impl ApplySecond for VecBrand {
111 fn apply_second<A, B>(fa: Apply<Self, (A,)>) -> impl Fn(Apply<Self, (B,)>) -> Apply<Self, (B,)>
121 where
122 Self: Kind<(A,)> + Kind<(B,)>,
123 Apply<Self, (A,)>: Clone,
124 B: Clone,
125 {
126 move |fb| {
127 let fb = <Self as Brand<_, (B,)>>::project(fb);
128 <Self as Brand<_, (_,)>>::inject(
129 <Self as Brand<_, (A,)>>::project(fa.to_owned())
130 .into_iter()
131 .flat_map(|_a| fb.iter().cloned())
132 .collect(),
133 )
134 }
135 }
136}
137
138impl Bind for VecBrand {
139 fn bind<F, A, B>(ma: Apply<Self, (A,)>) -> impl Fn(F) -> Apply<Self, (B,)>
148 where
149 Self: Kind<(A,)> + Kind<(B,)> + Sized,
150 F: Fn(A) -> Apply<Self, (B,)>,
151 Apply<Self, (A,)>: Clone,
152 {
153 move |f| {
154 <Self as Brand<_, (_,)>>::inject(
155 <Self as Brand<_, (_,)>>::project(ma.to_owned())
156 .into_iter()
157 .flat_map(|a| <Self as Brand<_, (B,)>>::project(f(a)))
158 .collect(),
159 )
160 }
161 }
162}