1#[cfg(all(not(feature = "std"), feature = "alloc"))]
5use alloc::{boxed::Box, vec::Vec};
6use core::marker::PhantomData;
7
8pub trait HKT {
13 type Of<T>;
14}
15
16pub struct OptionF;
18
19impl HKT for OptionF {
20 type Of<T> = Option<T>;
21}
22
23pub struct ResultF<E> {
25 _marker: PhantomData<E>,
26}
27
28impl<E> HKT for ResultF<E> {
29 type Of<T> = Result<T, E>;
30}
31
32#[cfg(any(feature = "std", feature = "alloc"))]
34pub struct VecF;
35
36#[cfg(any(feature = "std", feature = "alloc"))]
37impl HKT for VecF {
38 #[cfg(feature = "std")]
39 type Of<T> = Vec<T>;
40
41 #[cfg(all(not(feature = "std"), feature = "alloc"))]
42 type Of<T> = alloc::vec::Vec<T>;
43}
44
45pub trait HKT2 {
47 type P<A, B>;
48}
49
50pub struct ResultBF;
52
53impl HKT2 for ResultBF {
54 type P<A, B> = Result<B, A>;
55}
56
57pub struct TupleF;
59
60impl HKT2 for TupleF {
61 type P<A, B> = (A, B);
62}
63
64pub struct IdentityF;
66
67impl HKT for IdentityF {
68 type Of<T> = T;
69}
70
71#[cfg(any(feature = "std", feature = "alloc"))]
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub struct NonEmptyVec<T> {
75 pub head: T,
76 pub tail: Vec<T>,
77}
78
79#[cfg(any(feature = "std", feature = "alloc"))]
80impl<T> NonEmptyVec<T> {
81 pub fn new(head: T, tail: Vec<T>) -> Self {
82 Self { head, tail }
83 }
84
85 pub fn singleton(value: T) -> Self {
86 Self {
87 head: value,
88 tail: Vec::new(),
89 }
90 }
91
92 pub fn len(&self) -> usize {
93 1 + self.tail.len()
94 }
95
96 pub fn is_empty(&self) -> bool {
97 false }
99
100 pub fn iter(&self) -> impl Iterator<Item = &T> {
101 core::iter::once(&self.head).chain(self.tail.iter())
102 }
103
104 pub fn tails(&self) -> NonEmptyVec<NonEmptyVec<T>>
106 where
107 T: Clone,
108 {
109 let mut result_tail = Vec::new();
110 for i in 1..self.len() {
111 result_tail.push(NonEmptyVec::new(
112 self.tail[i - 1].clone(),
113 self.tail[i..].to_vec(),
114 ));
115 }
116 NonEmptyVec::new(self.clone(), result_tail)
117 }
118}
119
120#[cfg(any(feature = "std", feature = "alloc"))]
122pub struct NonEmptyVecF;
123
124#[cfg(any(feature = "std", feature = "alloc"))]
125impl HKT for NonEmptyVecF {
126 type Of<T> = NonEmptyVec<T>;
127}
128
129pub struct EnvF<E>(PhantomData<E>);
131
132impl<E> HKT for EnvF<E> {
133 type Of<T> = (E, T);
134}
135
136#[cfg(any(feature = "std", feature = "alloc"))]
138pub struct StoreF<S>(PhantomData<S>);
139
140#[cfg(any(feature = "std", feature = "alloc"))]
141impl<S: 'static> HKT for StoreF<S> {
142 type Of<T> = (Box<dyn Fn(S) -> T>, S);
143}
144
145#[cfg(any(feature = "std", feature = "alloc"))]
147pub struct TracedF<M>(PhantomData<M>);
148
149#[cfg(any(feature = "std", feature = "alloc"))]
150impl<M: 'static> HKT for TracedF<M> {
151 type Of<T> = Box<dyn Fn(M) -> T>;
152}
153
154#[cfg(any(feature = "std", feature = "alloc"))]
165pub struct ReaderF<E>(PhantomData<E>);
166
167#[cfg(any(feature = "std", feature = "alloc"))]
168impl<E: 'static> HKT for ReaderF<E> {
169 type Of<T> = Box<dyn Fn(E) -> T>;
170}
171
172#[cfg(any(feature = "std", feature = "alloc"))]
173impl<E: Clone + 'static> ReaderF<E> {
174 pub fn fmap<A: 'static, B: 'static>(
178 fa: Box<dyn Fn(E) -> A>,
179 f: impl Fn(A) -> B + 'static,
180 ) -> Box<dyn Fn(E) -> B> {
181 Box::new(move |e| f(fa(e)))
182 }
183
184 pub fn pure<A: Clone + 'static>(a: A) -> Box<dyn Fn(E) -> A> {
188 Box::new(move |_| a.clone())
189 }
190
191 pub fn chain<A: 'static, B: 'static>(
195 fa: Box<dyn Fn(E) -> A>,
196 f: impl Fn(A) -> Box<dyn Fn(E) -> B> + 'static,
197 ) -> Box<dyn Fn(E) -> B> {
198 Box::new(move |e: E| {
199 let a = fa(e.clone());
200 f(a)(e)
201 })
202 }
203
204 pub fn ask() -> Box<dyn Fn(E) -> E> {
208 Box::new(|e| e)
209 }
210
211 pub fn local<A: 'static>(
215 f: impl Fn(E) -> E + 'static,
216 reader: Box<dyn Fn(E) -> A>,
217 ) -> Box<dyn Fn(E) -> A> {
218 Box::new(move |e| reader(f(e)))
219 }
220}