use control::functor::Functor;
use control::applicative::Applicative;
use control::monad::Monad;
use algebra::{Monoid, Prod, Sum, Sequence};
use std::fmt;
#[test]
fn test_functor() {
let f = |x| x * 2;
assert!(Some(1).fmap(&f) == Some(2));
assert!(None.fmap(&f) == None);
}
#[test]
fn test_monad() {
let f = |x| Some(x * 2);
assert!(Some(1).fmap(&f).join() == Some(1).bind(&f));
assert!(None.fmap(&f).join() == None.bind(&f));
}
#[test]
fn test_applicative() {
let f = |x| x * 2;
assert_eq!(Some(&f).ap(Some(3)), Some(6));
assert_eq!(Some(&f).ap(None), None);
let none: Option<fn(i32) -> i32> = None;
assert_eq!(none.ap(Some(3)), None);
assert_eq!(none.ap(None), None);
}
fn check_monoid<M>(monoid: M)
where M: Monoid + PartialEq + Clone + fmt::Debug
{
assert_eq!(monoid.clone().mappend(M::mempty()), monoid.clone());
assert_eq!(M::mempty().mappend(monoid.clone()), monoid.clone());
}
#[test]
fn test_monoid() {
check_monoid(Sum(12.3));
check_monoid(Sum(4));
check_monoid(Prod(12.3));
check_monoid(Prod(4));
check_monoid(Sequence(vec![1, 2, 3]));
}