1use core::marker::PhantomData;
2
3pub trait HKT {
8 type Of<T>;
9}
10
11pub struct OptionF;
13
14impl HKT for OptionF {
15 type Of<T> = Option<T>;
16}
17
18pub struct ResultF<E> {
20 _marker: PhantomData<E>,
21}
22
23impl<E> HKT for ResultF<E> {
24 type Of<T> = Result<T, E>;
25}
26
27#[cfg(any(feature = "std", feature = "alloc"))]
29pub struct VecF;
30
31#[cfg(any(feature = "std", feature = "alloc"))]
32impl HKT for VecF {
33 #[cfg(feature = "std")]
34 type Of<T> = Vec<T>;
35
36 #[cfg(all(not(feature = "std"), feature = "alloc"))]
37 type Of<T> = alloc::vec::Vec<T>;
38}
39
40pub trait HKT2 {
42 type P<A, B>;
43}
44
45pub struct ResultBF;
47
48impl HKT2 for ResultBF {
49 type P<A, B> = Result<B, A>;
50}
51
52pub struct TupleF;
54
55impl HKT2 for TupleF {
56 type P<A, B> = (A, B);
57}
58
59pub struct IdentityF;
61
62impl HKT for IdentityF {
63 type Of<T> = T;
64}
65
66#[cfg(any(feature = "std", feature = "alloc"))]
68#[derive(Debug, Clone, PartialEq, Eq)]
69pub struct NonEmptyVec<T> {
70 pub head: T,
71 pub tail: Vec<T>,
72}
73
74#[cfg(any(feature = "std", feature = "alloc"))]
75impl<T> NonEmptyVec<T> {
76 pub fn new(head: T, tail: Vec<T>) -> Self {
77 Self { head, tail }
78 }
79
80 pub fn singleton(value: T) -> Self {
81 Self {
82 head: value,
83 tail: Vec::new(),
84 }
85 }
86
87 pub fn len(&self) -> usize {
88 1 + self.tail.len()
89 }
90
91 pub fn is_empty(&self) -> bool {
92 false }
94
95 pub fn iter(&self) -> impl Iterator<Item = &T> {
96 core::iter::once(&self.head).chain(self.tail.iter())
97 }
98
99 pub fn tails(&self) -> NonEmptyVec<NonEmptyVec<T>>
101 where
102 T: Clone,
103 {
104 let mut result_tail = Vec::new();
105 for i in 1..self.len() {
106 result_tail.push(NonEmptyVec::new(
107 self.tail[i - 1].clone(),
108 self.tail[i..].to_vec(),
109 ));
110 }
111 NonEmptyVec::new(self.clone(), result_tail)
112 }
113}
114
115#[cfg(any(feature = "std", feature = "alloc"))]
117pub struct NonEmptyVecF;
118
119#[cfg(any(feature = "std", feature = "alloc"))]
120impl HKT for NonEmptyVecF {
121 type Of<T> = NonEmptyVec<T>;
122}
123
124pub struct EnvF<E>(PhantomData<E>);
126
127impl<E> HKT for EnvF<E> {
128 type Of<T> = (E, T);
129}
130
131#[cfg(any(feature = "std", feature = "alloc"))]
133pub struct StoreF<S>(PhantomData<S>);
134
135#[cfg(any(feature = "std", feature = "alloc"))]
136impl<S: 'static> HKT for StoreF<S> {
137 type Of<T> = (Box<dyn Fn(S) -> T>, S);
138}
139
140#[cfg(any(feature = "std", feature = "alloc"))]
142pub struct TracedF<M>(PhantomData<M>);
143
144#[cfg(any(feature = "std", feature = "alloc"))]
145impl<M: 'static> HKT for TracedF<M> {
146 type Of<T> = Box<dyn Fn(M) -> T>;
147}
148
149#[cfg(any(feature = "std", feature = "alloc"))]
160pub struct ReaderF<E>(PhantomData<E>);
161
162#[cfg(any(feature = "std", feature = "alloc"))]
163impl<E: 'static> HKT for ReaderF<E> {
164 type Of<T> = Box<dyn Fn(E) -> T>;
165}
166
167#[cfg(any(feature = "std", feature = "alloc"))]
168impl<E: Clone + 'static> ReaderF<E> {
169 pub fn fmap<A: 'static, B: 'static>(
173 fa: Box<dyn Fn(E) -> A>,
174 f: impl Fn(A) -> B + 'static,
175 ) -> Box<dyn Fn(E) -> B> {
176 Box::new(move |e| f(fa(e)))
177 }
178
179 pub fn pure<A: Clone + 'static>(a: A) -> Box<dyn Fn(E) -> A> {
183 Box::new(move |_| a.clone())
184 }
185
186 pub fn chain<A: 'static, B: 'static>(
190 fa: Box<dyn Fn(E) -> A>,
191 f: impl Fn(A) -> Box<dyn Fn(E) -> B> + 'static,
192 ) -> Box<dyn Fn(E) -> B> {
193 Box::new(move |e: E| {
194 let a = fa(e.clone());
195 f(a)(e)
196 })
197 }
198
199 pub fn ask() -> Box<dyn Fn(E) -> E> {
203 Box::new(|e| e)
204 }
205
206 pub fn local<A: 'static>(
210 f: impl Fn(E) -> E + 'static,
211 reader: Box<dyn Fn(E) -> A>,
212 ) -> Box<dyn Fn(E) -> A> {
213 Box::new(move |e| reader(f(e)))
214 }
215}