scsys_core/hkt/
applicative.rs1use super::functor::Functor;
9use super::HKT;
10
11use super::containers::*;
12
13pub trait Applicative<U>: Functor<U> {
14 fn pure_(value: U) -> Self::T
15 where
16 Self: HKT<U, C = U>;
17 fn seq<F>(&self, fs: <Self as HKT<F>>::T) -> <Self as HKT<U>>::T
18 where
19 F: Fn(&<Self as HKT<U>>::C) -> U,
20 Self: HKT<F>;
21}
22
23#[allow(unused_macros)]
24macro_rules! applicative {
25 ($($t:ident),* $(,)?) => {
26 $(
27 applicative!(@impl $t);
28 )*
29 };
30 (@impl $t:ident) => {
31 impl<T, U> Applicative<U> for $t<T> {
32 fn pure_(value: U) -> Self::T {
33 $t::new(value)
34 }
35
36 fn seq<F>(&self, fs: <Self as HKT<F>>::T) -> $t<U>
37 where
38 F: Fn(&<Self as HKT<U>>::C) -> U,
39 {
40 let v = fs(self);
41 $t::new(v)
42 }
43 }
44 };
45}
46
47#[cfg(feature = "alloc")]
48applicative!(Arc, Box, Rc);
49
50impl<T, U> Applicative<U> for Option<T> {
51 fn pure_(value: U) -> Self::T {
52 Some(value)
53 }
54
55 fn seq<F>(&self, fs: <Self as HKT<F>>::T) -> Option<U>
56 where
57 F: Fn(&T) -> U,
58 {
59 match *self {
60 Some(ref value) => match fs {
61 Some(f) => Some(f(value)),
62 None => None,
63 },
64 None => None,
65 }
66 }
67}
68
69#[cfg(feature = "alloc")]
70impl<T, U> Applicative<U> for Vec<T> {
71 fn pure_(value: U) -> Self::T {
72 vec![value]
73 }
74
75 fn seq<F>(&self, fs: <Self as HKT<F>>::T) -> Vec<U>
76 where
77 F: Fn(&T) -> U,
78 {
79 let mut result = Vec::new();
80 for (i, f) in fs.into_iter().enumerate() {
81 let v = (f)(&self[i]);
82 result.push(v)
83 }
84 return result;
85 }
86}