scala/ScalaBook/chapter-03/genStack4.scala
abstract class Stack{
type Q
def push(x: Q):Stack
def pop:Stack
def top:Q
}
case object EmptyStack extends Stack {
def push(x: Any) = new StackC(x,this)
def pop:Stack =
throw new NoSuchElementException("stack underflow")
def top : Any =
throw new NoSuchElementException("top of empty stack")
}
case class StackC(e: Q, s: Stack) extends Stack {
type Q
def this(e : Q) = this(e, EmptyStack.asInstanceOf[Stack])
def push (x : Q) = new StackC(x, this)
def pop = s
def top = e.asInstanceOf[Q]
}
Stack {type Q = Int }
StacjC {type Q = Int }
val q0 = new StackC(5)
val q1 = StackC(3,StackC(4,q0))
println(q1)
val q2 = q1.pop
println(q2)
val q3 = q2.pop
println(q3)
val q4 = q3.push(9)
println(q4)
var x = 7 + q4.top
println("x = " + x)
Stack {type Q = String }
StacjC {type Q = String }
val s1 = new StackC[String]("a")
val s2 = s1.push("b")
println(s2)