// run-pass #![allow(non_camel_case_types)] trait vec_monad { fn bind(&self, f: F ) -> Vec where F: FnMut(&A) -> Vec ; } impl vec_monad for Vec { fn bind(&self, mut f: F) -> Vec where F: FnMut(&A) -> Vec { let mut r = Vec::new(); for elt in self { r.extend(f(elt)); } r } } trait option_monad { fn bind(&self, f: F) -> Option where F: FnOnce(&A) -> Option; } impl option_monad for Option { fn bind(&self, f: F) -> Option where F: FnOnce(&A) -> Option { match *self { Some(ref a) => { f(a) } None => { None } } } } fn transform(x: Option) -> Option { x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_string()) ) } pub fn main() { assert_eq!(transform(Some(10)), Some("11".to_string())); assert_eq!(transform(None), None); assert_eq!((vec!["hi".to_string()]) .bind(|x| vec![x.clone(), format!("{}!", x)] ) .bind(|x| vec![x.clone(), format!("{}?", x)] ), ["hi".to_string(), "hi?".to_string(), "hi!".to_string(), "hi!?".to_string()]); }