Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 2nd, 2012  |  syntax: None  |  size: 1.53 KB  |  hits: 13  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Change node in Scala case class tree
  2. abstract class Tree
  3. case class Branch(b1:Tree,b2:Tree, value:Int) extends Tree
  4. case class Leaf(value:Int) extends Tree
  5. var tree = Branch(Branch(Leaf(1),Leaf(2),3),Branch(Leaf(4), Leaf(5),6))
  6.        
  7. // Changed Tree to Node, b/c that seems more accurate
  8. // Since Branch and Leaf both have value, pull that up to base class
  9. sealed abstract class Node(val value: Int) {
  10.   /** Replaces this node or its children according to the given function */
  11.   def replace(fn: Node => Node): Node
  12.  
  13.   /** Helper to replace nodes that have a given value */
  14.   def replace(value: Int, node: Node): Node =
  15.     replace(n => if (n.value == value) node else n)
  16. }
  17.  
  18. // putting value first makes class structure match tree structure
  19. case class Branch(override val value: Int, left: Node, right: Node)
  20.      extends Node(value) {
  21.   def replace(fn: Node => Node): Node = {
  22.     val newSelf = fn(this)
  23.  
  24.     if (this eq newSelf) {
  25.       // this node's value didn't change, check the children
  26.       val newLeft = left.replace(fn)
  27.       val newRight = right.replace(fn)
  28.  
  29.       if ((left eq newLeft) && (right eq newRight)) {
  30.         // neither this node nor children changed
  31.         this
  32.       } else {
  33.         // change the children of this node
  34.         copy(left = newLeft, right = newRight)
  35.       }
  36.     } else {
  37.       // change this node
  38.       newSelf
  39.     }
  40.   }
  41. }
  42.        
  43. val tree1 = Branch(Branch(Leaf(1),Leaf(2),3),Branch(Leaf(4), Leaf(5),6))
  44. val tree2 = tree1.copy(b2 = tree1.b2.copy(b1 = Leaf(5))
  45. // -> Branch(Branch(Leaf(1),Leaf(2),3),Branch(Leaf(5), Leaf(5),6))