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