1use crate::applicative::Applicative;
2use crate::chain::Chain;
3
4pub trait Monad: Applicative + Chain {}
10
11impl<F: Applicative + Chain> Monad for F {}
12
13#[cfg(test)]
14mod law_tests {
15 use crate::applicative::Applicative;
16 use crate::chain::Chain;
17 use crate::hkt::OptionF;
18 #[cfg(any(feature = "std", feature = "alloc"))]
19 use crate::hkt::VecF;
20 use proptest::prelude::*;
21
22 proptest! {
23 #[test]
25 fn option_left_identity(a in any::<i32>()) {
26 let f = |x: i32| Some(x.wrapping_mul(2));
27 let left = OptionF::chain(OptionF::pure(a), f);
28 let right = f(a);
29 prop_assert_eq!(left, right);
30 }
31
32 #[test]
34 fn option_right_identity(m in any::<Option<i32>>()) {
35 let left = OptionF::chain(m, OptionF::pure);
36 prop_assert_eq!(left, m);
37 }
38
39 #[test]
40 fn vec_left_identity(a in any::<i32>()) {
41 let f = |x: i32| vec![x, x.wrapping_add(1)];
42 let left = VecF::chain(VecF::pure(a), f);
43 let right = f(a);
44 prop_assert_eq!(left, right);
45 }
46
47 #[test]
48 fn vec_right_identity(m in prop::collection::vec(any::<i32>(), 0..10)) {
49 let left = VecF::chain(m.clone(), VecF::pure);
50 prop_assert_eq!(left, m);
51 }
52 }
53}