1#[doc(inline)]
9pub use self::{applicative::*, functor::*, monad::*};
10
11mod applicative;
12mod functor;
13mod monad;
14
15pub(crate) mod prelude {
16 pub use super::applicative::Applicative;
17 pub use super::functor::Functor;
18 pub use super::monad::Monad;
19 pub use super::HKT;
20}
21
22pub(crate) mod containers {
23 pub(crate) use core::option::Option;
24
25 #[cfg(feature = "alloc")]
26 pub(crate) use alloc::{boxed::Box, rc::Rc, sync::Arc, vec::Vec};
27}
28
29pub trait HKT<U> {
30 type C; type T; }
33
34#[macro_export]
35macro_rules! hkt {
36 ($($($p:ident)::*),* $(,)?) => {
37 $(
38 $crate::hkt!(@impl $($p)::*);
39 )*
40 };
41 (@impl $($p:ident)::*) => {
42 impl<T, U> HKT<U> for $($p)::*<T> {
43 type C = T;
44 type T = $($p)::*<U>;
45 }
46 };
47}
48
49hkt!(containers::Option);
50
51#[cfg(feature = "alloc")]
52hkt!(
53 containers::Arc,
54 containers::Box,
55 containers::Rc,
56 containers::Vec
57);
58
59#[allow(unused_imports)]
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[cfg(feature = "alloc")]
65 #[test]
66 fn test_hkt_vec() {
67 let v = Vec::from_iter(0..9);
68 let v2 = v.fmap(|x| (x + 1).to_string());
69 assert_eq!(v2, ["1", "2", "3", "4", "5", "6", "7", "8", "9"]);
70
71 let v = Vec::return_(0);
72 let v2 = v.bind(|x| vec![x + 1]);
73 assert_eq!(v2, [1]);
74 }
75}