1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
use applicative::Applicative; use bind::Bind; use std::rc::Rc; pub trait Monad: Bind + Applicative {} macro_rules! monad_numeric_impl { ($($t:ty)*) => ($( impl Monad for $t {} )*) } monad_numeric_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } impl<A> Monad for Rc<A> {} impl<A> Monad for Box<A> {} impl<A> Monad for Option<A> {} impl<A, E: Clone> Monad for Result<A, E> {} impl<A> Monad for Vec<A> {} #[cfg(test)] mod laws { use bind::Bind; use pure::Pure; #[quickcheck] fn monad_left_identity_law(n: i64) { assert_eq!(Option::pure(n).bind(|x| Option::pure(*x)), Option::pure(n)) } #[quickcheck] fn monad_right_identity_law(n: i64) { assert_eq!( Option::pure(n) .bind(|x| Option::pure(*x)) .bind(|y| Option::pure(*y)), Option::pure(n).bind(|x| Option::pure(*x).bind(|y| Option::pure(*y))) ) } }