functo_rs/
data.rs

1//! Data functors abstracts over data-like structures, which can cosume continuations as many times as they want.
2//! Some of data functors can be [control functors][`crate::control`], which can consume continuations at most once.
3
4use std::fmt::{Debug, Formatter};
5use std::marker::PhantomData;
6
7pub use crate::impls::*;
8
9/// A type-level label to force qualified_do to use `data::Functor`-hierarchy.
10pub struct AsData<F>(PhantomData<F>);
11
12impl<G: Functor> AsData<G> {
13    #[inline(always)]
14    pub fn fmap<A, B, F>(f: F, fa: G::Container<A>) -> G::Container<B>
15    where
16        F: FnMut(A) -> B,
17    {
18        G::fmap(f, fa)
19    }
20}
21
22pub trait Functor {
23    type Container<T>;
24
25    fn fmap<A, B, F>(f: F, fa: Self::Container<A>) -> Self::Container<B>
26    where
27        F: FnMut(A) -> B;
28}
29
30impl Functor for Identity {
31    type Container<T> = T;
32
33    #[inline(always)]
34    fn fmap<A, B, F>(mut f: F, a: A) -> B
35    where
36        F: FnMut(A) -> B,
37    {
38        f(a)
39    }
40}
41
42impl Functor for UndetVec {
43    type Container<T> = Vec<T>;
44
45    #[inline(always)]
46    fn fmap<A, B, F>(f: F, fa: Self::Container<A>) -> Self::Container<B>
47    where
48        F: FnMut(A) -> B,
49    {
50        fa.into_iter().map(f).collect()
51    }
52}
53
54impl Functor for ZipVec {
55    type Container<T> = Vec<T>;
56
57    #[inline(always)]
58    fn fmap<A, B, F>(f: F, fa: Self::Container<A>) -> Self::Container<B>
59    where
60        F: FnMut(A) -> B,
61    {
62        fa.into_iter().map(f).collect()
63    }
64}
65
66impl Functor for OptionFunctor {
67    type Container<T> = Option<T>;
68
69    #[inline(always)]
70    fn fmap<A, B, F>(f: F, fa: Self::Container<A>) -> Self::Container<B>
71    where
72        F: FnMut(A) -> B,
73    {
74        fa.map(f)
75    }
76}
77
78impl<E> Functor for ResultFunctor<E> {
79    type Container<T> = Result<T, E>;
80
81    #[inline(always)]
82    fn fmap<A, B, F>(f: F, fa: Self::Container<A>) -> Self::Container<B>
83    where
84        F: FnMut(A) -> B,
85    {
86        fa.map(f)
87    }
88}
89
90impl Functor for V2 {
91    type Container<T> = (T, T);
92
93    #[inline(always)]
94    fn fmap<A, B, F>(mut f: F, (a1, a2): Self::Container<A>) -> Self::Container<B>
95    where
96        F: FnMut(A) -> B,
97    {
98        (f(a1), f(a2))
99    }
100}
101
102impl<const N: usize> Functor for ArrayFunctor<N> {
103    type Container<T> = [T; N];
104
105    #[inline(always)]
106    fn fmap<A, B, F>(f: F, fa: Self::Container<A>) -> Self::Container<B>
107    where
108        F: FnMut(A) -> B,
109    {
110        fa.map(f)
111    }
112}
113
114pub trait Pointed: Functor {
115    fn pure<T: Clone>(t: T) -> Self::Container<T>;
116}
117
118impl<G: Pointed> AsData<G> {
119    #[inline(always)]
120    pub fn pure<T: Clone>(t: T) -> G::Container<T> {
121        G::pure(t)
122    }
123}
124
125impl Pointed for Identity {
126    #[inline(always)]
127    fn pure<T: Clone>(t: T) -> T {
128        t
129    }
130}
131
132impl Pointed for OptionFunctor {
133    #[inline(always)]
134    fn pure<T: Clone>(t: T) -> Option<T> {
135        Some(t)
136    }
137}
138
139impl<E> Pointed for ResultFunctor<E> {
140    #[inline(always)]
141    fn pure<T: Clone>(t: T) -> Result<T, E> {
142        Ok(t)
143    }
144}
145
146impl Pointed for UndetVec {
147    #[inline(always)]
148    fn pure<T: Clone>(t: T) -> Vec<T> {
149        vec![t]
150    }
151}
152
153impl Pointed for V2 {
154    #[inline(always)]
155    fn pure<T: Clone>(t: T) -> (T, T) {
156        (t.clone(), t)
157    }
158}
159
160#[derive(Clone)]
161pub(crate) struct WrapArrayStruct<U>(pub(crate) U);
162impl<U> Debug for WrapArrayStruct<U> {
163    #[inline(always)]
164    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165        f.write_str("<ELEMENT>")
166    }
167}
168
169#[inline(always)]
170pub(crate) fn unsafe_collect_array<const N: usize, I>(iter: I) -> [I::Item; N]
171where
172    I: Iterator,
173{
174    <[WrapArrayStruct<I::Item>; N]>::try_from(iter.map(WrapArrayStruct).collect::<Vec<_>>())
175        .unwrap()
176        .map(|WrapArrayStruct(t)| t)
177}
178
179impl<const N: usize> Pointed for ArrayFunctor<N> {
180    fn pure<T: Clone>(t: T) -> [T; N] {
181        unsafe_collect_array(itertools::repeat_n(t, N))
182    }
183}
184
185pub trait Apply: Functor {
186    fn zip_with<A, B, C, F>(
187        f: F,
188        fa: Self::Container<A>,
189        fb: Self::Container<B>,
190    ) -> Self::Container<C>
191    where
192        F: FnMut(A, B) -> C;
193
194    #[inline(always)]
195    fn ap<A, B, F>(ff: Self::Container<F>, fa: Self::Container<A>) -> Self::Container<B>
196    where
197        F: FnOnce(A) -> B,
198    {
199        Self::zip_with(|f, a| f(a), ff, fa)
200    }
201}
202
203impl<G: Apply> AsData<G> {
204    #[inline(always)]
205    pub fn zip_with<A, B, C, F>(f: F, fa: G::Container<A>, fb: G::Container<B>) -> G::Container<C>
206    where
207        F: FnMut(A, B) -> C,
208    {
209        G::zip_with(f, fa, fb)
210    }
211
212    #[inline(always)]
213    pub fn ap<A, B, F>(ff: G::Container<F>, fa: G::Container<A>) -> G::Container<B>
214    where
215        F: FnOnce(A) -> B,
216    {
217        G::ap(ff, fa)
218    }
219}
220
221impl Apply for Identity {
222    #[inline(always)]
223    fn zip_with<A, B, C, F>(mut f: F, a: A, b: B) -> C
224    where
225        F: FnMut(A, B) -> C,
226    {
227        f(a, b)
228    }
229}
230
231impl Apply for OptionFunctor {
232    #[inline(always)]
233    fn zip_with<A, B, C, F>(
234        mut f: F,
235        fa: Self::Container<A>,
236        fb: Self::Container<B>,
237    ) -> Self::Container<C>
238    where
239        F: FnMut(A, B) -> C,
240    {
241        fa.zip(fb).map(|(a, b)| f(a, b))
242    }
243}
244
245impl<E> Apply for ResultFunctor<E> {
246    #[inline(always)]
247    fn zip_with<A, B, C, F>(
248        mut f: F,
249        fa: Self::Container<A>,
250        fb: Self::Container<B>,
251    ) -> Self::Container<C>
252    where
253        F: FnMut(A, B) -> C,
254    {
255        fa.and_then(|a| fb.map(|b| f(a, b)))
256    }
257}
258
259impl Apply for ZipVec {
260    #[inline(always)]
261    fn zip_with<A, B, C, F>(
262        mut f: F,
263        fa: Self::Container<A>,
264        fb: Self::Container<B>,
265    ) -> Self::Container<C>
266    where
267        F: FnMut(A, B) -> C,
268    {
269        fa.into_iter().zip(fb).map(|(a, b)| f(a, b)).collect()
270    }
271}
272
273impl Apply for V2 {
274    #[inline(always)]
275    fn zip_with<A, B, C, F>(
276        mut f: F,
277        fa: Self::Container<A>,
278        fb: Self::Container<B>,
279    ) -> Self::Container<C>
280    where
281        F: FnMut(A, B) -> C,
282    {
283        (f(fa.0, fb.0), f(fa.1, fb.1))
284    }
285}
286
287impl<const N: usize> Apply for ArrayFunctor<N> {
288    #[inline(always)]
289    fn zip_with<A, B, C, F>(
290        mut f: F,
291        fa: Self::Container<A>,
292        fb: Self::Container<B>,
293    ) -> Self::Container<C>
294    where
295        F: FnMut(A, B) -> C,
296    {
297        unsafe_collect_array(fa.into_iter().zip(fb).map(|(a, b)| f(a, b)))
298    }
299}
300
301pub trait Alternative: Apply + Pointed {
302    fn empty<T>() -> Self::Container<T>;
303    fn choice<T>(a: Self::Container<T>, b: Self::Container<T>) -> Self::Container<T>;
304
305    #[inline(always)]
306    fn guard(p: bool) -> Self::Container<()> {
307        if p {
308            Self::pure(())
309        } else {
310            Self::empty()
311        }
312    }
313}
314
315impl<G: Alternative> AsData<G> {
316    #[inline(always)]
317    pub fn empty<T>() -> G::Container<T> {
318        G::empty()
319    }
320
321    #[inline(always)]
322    pub fn choice<T>(a: G::Container<T>, b: G::Container<T>) -> G::Container<T> {
323        G::choice(a, b)
324    }
325
326    #[inline(always)]
327    pub fn guard(p: bool) -> G::Container<()> {
328        G::guard(p)
329    }
330}
331
332impl Alternative for OptionFunctor {
333    #[inline(always)]
334    fn empty<T>() -> Option<T> {
335        None
336    }
337
338    #[inline(always)]
339    fn choice<T>(a: Self::Container<T>, b: Self::Container<T>) -> Self::Container<T> {
340        a.or(b)
341    }
342}
343
344impl<E: Default> Alternative for ResultFunctor<E> {
345    #[inline(always)]
346    fn empty<T>() -> Result<T, E> {
347        Err(E::default())
348    }
349
350    #[inline(always)]
351    fn choice<T>(a: Self::Container<T>, b: Self::Container<T>) -> Self::Container<T> {
352        a.or(b)
353    }
354}