funlib/monad/
mod.rs

1//!
2//! Monad implementations and tests
3//!
4
5use crate::Monad;
6use std::boxed::Box;
7use std::rc::Rc;
8
9impl<A, B> Monad<B> for Option<A> {
10  fn bind<F>(&self, mut f: F) -> Option<B> where F: FnMut(&A) -> Option<B> {
11    match *self {
12      Some(ref a) => f(a),
13      None => None,
14    }
15  }
16}
17
18impl<A, B> Monad<B> for Box<A> {
19  fn bind<F>(&self, mut f: F) -> Box<B> where F: FnMut(&A) -> Box<B> {
20    f(self)
21  }
22}
23
24impl<A, B> Monad<B> for Rc<A> {
25  fn bind<F>(&self, mut f: F) -> Rc<B> where F: FnMut(&A) -> Rc<B> {
26    f(self)
27  }
28}
29
30impl<A, B> Monad<B> for Vec<A> {
31  fn bind<F>(&self, f: F) -> Vec<B> where F: FnMut(&A) -> Vec<B> {
32    self.iter().flat_map(f).collect()
33  }
34}
35
36#[cfg(test)]
37mod test {
38  use crate::Monad;
39  use crate::Functor;
40  use crate::Applicative;
41  use std::rc::Rc;
42
43  #[test]
44  fn option() {
45    assert_eq!(Some("hello"), Some(5).fmap(|_i| "hello"));
46    assert_eq!(Option::<i32>::pure_(10), Some(5).bind(|i| Some(i * 1)).fmap(|i| i * 2));
47    assert_eq!(Option::<i32>::pure_(10), Some(5).bind(|i| Some(i * 2)));
48  }
49
50  #[test]
51  fn box_() {
52    assert_eq!(Box::pure_(10), Box::pure_(5).bind(|i| Box::new(i * 2)));
53  }
54
55  #[test]
56  fn rc() {
57    assert_eq!(Rc::pure_(10), Rc::pure_(5).bind(|i| Rc::new(i * 2)));
58  }
59
60  #[test]
61  fn vec() {
62    let mut vec = Vec::pure_(1);
63    vec.push(2);
64    vec.push(3);
65    assert_eq!(vec![1,2,2,4,3,6], vec.bind(|x| vec![x * 1, x * 2]));
66  }
67}