===== Lecture 5. Functional vs OO decomposition ===== /* Functional implementation Functional decomposition (patterns) */ /* trait Nat case object Zero extends Nat case class Succ(n: Nat) extends Nat case object Infty extends Nat def isZero(n: Nat): Boolean = n match { case Zero => true case _ => false } def add(n: Nat, m: Nat): Nat = n match { case Zero => m case Succ(np) => Succ(add(np,m)) case Infty => n } def equals(n: Nat, m: Nat): Boolean = (n,m) match { case (Zero, Zero) => true case (Succ(np), Succ(mp)) => equals(np,mp) case (Infty,Infty) => true case _ => false } //add(Succ(Succ(Zero)), Succ(Zero)) def subtract(n: Nat, m: Nat): Nat = (n,m) match { case (Zero,_) => Zero case (_,Zero) => n case (Succ(np),Succ(mp)) => subtract(np,mp) case (Infty,_) => n } */ // OOriented implementation // OOriented decomposition trait Nat { def isZero: Boolean def add(other: Nat): Nat def equals(other: Nat): Boolean def subtract(other: Nat): Nat } case object Zero extends Nat { override def isZero: Boolean = true override def add(other: Nat):Nat = other override def equals(other: Nat): Boolean = other match { case Zero => true case _ => false } override def subtract(other: Nat): Nat = this } case class Succ(n: Nat) extends Nat { override def isZero: Boolean = false override def add(other: Nat): Nat = Succ(n.add(other)) override def equals(other: Nat): Boolean = other match { case Zero => false case Succ(mp) => n.equals(mp) } override def subtract(other: Nat): Nat = other match { case Zero => this case Succ(mp) => n.subtract(mp) } } case object Infty extends Nat { override def isZero: Boolean = false override def add(other: Nat): Nat = this override def equals(other: Nat): Boolean = other match { case Infty => true case _ => false } override def subtract(other: Nat): Nat = this } // Scenario 1: We want to add a new function: subtraction: // What do we have to do?! // OO implementation // Scenario 2: We want to add a new value to the type