// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. 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()]); }