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