1use crate::{
4 brands::{Brand, Brand1},
5 functions::{identity, map},
6 hkt::{Apply, Kind, Kind1},
7 typeclasses::{Apply as TypeclassApply, ApplyFirst, ApplySecond, Bind, Functor, Pure},
8};
9
10#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
12pub struct Solo<A>(pub A);
13
14pub struct SoloBrand;
16
17impl<A> Kind1<A> for SoloBrand {
18 type Output = Solo<A>;
19}
20
21impl<A> Brand1<Solo<A>, A> for SoloBrand {
22 fn inject(a: Solo<A>) -> Apply<Self, (A,)> {
23 a
24 }
25 fn project(a: Apply<Self, (A,)>) -> Solo<A> {
26 a
27 }
28}
29
30impl Pure for SoloBrand {
31 fn pure<A>(a: A) -> Apply<Self, (A,)> {
39 Solo(a)
40 }
41}
42
43impl Functor for SoloBrand {
44 fn map<F, A, B>(f: F) -> impl Fn(Apply<Self, (A,)>) -> Apply<Self, (B,)>
52 where
53 Self: Kind<(A,)> + Kind<(B,)>,
54 F: Fn(A) -> B,
55 {
56 move |fa| <Self as Brand<_, _>>::inject(Solo(f(<Self as Brand<_, _>>::project(fa).0)))
57 }
58}
59
60impl TypeclassApply for SoloBrand {
61 fn apply<F, A, B>(ff: Apply<Self, (F,)>) -> impl Fn(Apply<Self, (A,)>) -> Apply<Self, (B,)>
69 where
70 Self: Kind<(F,)> + Kind<(A,)> + Kind<(B,)>,
71 F: Fn(A) -> B,
72 Apply<Self, (F,)>: Clone,
73 {
74 map::<Self, _, _, _>(<Self as Brand<Solo<F>, _>>::project(ff.to_owned()).0)
75 }
76}
77
78impl ApplyFirst for SoloBrand {
79 fn apply_first<A, B>(fa: Apply<Self, (A,)>) -> impl Fn(Apply<Self, (B,)>) -> Apply<Self, (A,)>
87 where
88 Self: Kind<(A,)> + Kind<(B,)>,
89 Apply<Self, (A,)>: Clone,
90 {
91 move |_fb| fa.to_owned()
92 }
93}
94
95impl ApplySecond for SoloBrand {
96 fn apply_second<A, B>(_fa: Apply<Self, (A,)>) -> impl Fn(Apply<Self, (B,)>) -> Apply<Self, (B,)>
104 where
105 Self: Kind<(A,)> + Kind<(B,)>,
106 {
107 identity
108 }
109}
110
111impl Bind for SoloBrand {
112 fn bind<F, A, B>(ma: Apply<Self, (A,)>) -> impl Fn(F) -> Apply<Self, (B,)>
120 where
121 Self: Kind<(A,)> + Kind<(B,)> + Sized,
122 F: Fn(A) -> Apply<Self, (B,)>,
123 Apply<Self, (A,)>: Clone,
124 {
125 move |f| f(<Self as Brand<_, _>>::project(ma.to_owned()).0)
126 }
127}