// listo.rs - Owned List struct Node { head : int, tail : Option<~Node> } type List = Option<~Node> ; trait Map { fn mapr(&self, &fn(int) -> int) -> List; } impl Map for List { fn mapr(&self, f: &fn(int) -> int) -> List { match(*self) { None => None, // need the ref here to keep the matched variable type borrowed Some(ref node) => { Some(~Node{ head: f(node.head), tail: node.tail.mapr(f) }) }, } } } impl ToStr for List { fn to_str(&self) -> ~str { fn elements_to_str(n: &~Node) -> ~str { match (n.tail) { None => fmt!("%?", n.head), Some(ref tail) => fmt!("%?, %s", n.head, elements_to_str(tail)) } } match(*self) { None => ~"Null", Some(ref n) => fmt!("[%s]", elements_to_str(n)) } } } fn main() { let lst0 : List = Some(~Node{head: 1, tail: Some(~Node{head : 2, tail: Some(~Node{head: 3, tail: None})})}); println(lst0.to_str()); let lst1 = lst0.mapr(|x: int| { x + 1 }); println(lst1.to_str()); let lst2 = lst1.mapr(|x: int| { x * x }); println(lst2.to_str()); let lst3 = lst2.mapr(|x: int| { if x % 2 == 0 { x } else { -x }}); println(lst3.to_str()); println(lst0.to_str()); }