Skip to content

Instantly share code, notes, and snippets.

@lambda-hacker
Last active April 26, 2017 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lambda-hacker/e62607c7d33d3a2d4ddd to your computer and use it in GitHub Desktop.
Save lambda-hacker/e62607c7d33d3a2d4ddd to your computer and use it in GitHub Desktop.
Stack using List [Scala]
// Immutable Stack Type using List
class Stack[A] (val elems: List[A] = List.empty[A]) {
def push(v: A) : Stack[A] = new Stack(v :: elems)
def pushAll(xs: Iterable[A]) : Stack[A] =
xs.foldLeft (this) ((accStack, e) => accStack.push(e))
def pop() : Stack[A] = new Stack(elems.tail)
def pop2() : (A, Stack[A]) = (elems.head, new Stack(elems.tail))
def pop3() : (Option[A], Stack[A]) = if (isEmpty) (None, this)
else (Some(elems.head), pop())
def top : Option[A] = if (!isEmpty) Some(elems.head) else None
def size : Int = elems.length
def isEmpty : Boolean = (elems == List.empty)
def apply(i: Int) : A = elems(i)
def +:(e: A) : Stack[A] = push(e)
def :+(e: A) : Stack[A] = push(e)
def unary_-() : Stack[A] = pop()
override def toString = elems.mkString("\n")
}
// Stack was tested against Scala REPL
//companion object
object Stack {
def apply[A](elems: List[A] = List.empty[A]) = new Stack(elems)
}
// Stack Type using List
import scala.util.control.Exception
class Stack[A] (var elems: List[A] = List.empty[A]) {
def push(v: A) : Stack[A] = {
elems = v :: elems;
this
}
def pushAll(xs: Iterable[A]) : Stack[A] = {
xs.foreach (push(_))
this
}
def pop() : A = if (!this.isEmpty) {
val popped = elems.head
elems = elems.tail
popped
} else throw new Exception("Empty Stack")
def top : A = if (!this.isEmpty) { elems.head }
else throw new Exception("Empty Stack")
def isEmpty : Boolean = (elems == List.empty)
def size : Int = elems.length
def apply(i: Int) : A = elems(i)
def +:(e: A) : Stack[A] = push(e)
def :+(e: A) : Stack[A] = push(e)
def unary_-() : Stack[A] = { pop(); this }
override def toString = elems.mkString("\n")
}
// Stack was tested against Scala REPL
// Defining Main
object Main extends App {
val myStack = new Stack[String]
myStack.push("Wow").push("Err").push("Hi").push("Hackers")
println ("Stack Size = " + myStack.size)
println ("Stack: \n" + myStack)
println
println ("Is Empty = " + myStack.isEmpty)
println ("Top = " + myStack.top)
println
println ("Popping... " + myStack.pop())
println ("Popping... " + myStack.pop())
myStack.pushAll(Vector("Universe", "World", "Earth")).pushAll(List("Scala", "Haskell"))
println ("Stack: \n" + myStack)
println ("Popping... " + myStack.pop())
println ("Popping... " + myStack.pop())
println ("Stack Size = " + myStack.size)
println ("Top = " + myStack.top)
println ("Stack[2] = " + myStack(2))
while (!myStack.isEmpty) println ("Popping... " + myStack.pop())
println ("Is Empty = " + myStack.isEmpty)
println ("Stack Size = " + myStack.size)
"Yay" +: "Foo" +: myStack
myStack :+ "Wohoo" :+ "Bar"
println (myStack)
-myStack // Pops
-(-(-myStack)) // Pops 3 times
println ("Popping... " + myStack.pop()) // Should throw an exception
// println ("Top = " + myStack.top) // Should thow an exception
}
@tabrez
Copy link

tabrez commented Jan 30, 2015

You can do it in a couple of ways.

  1. Parameterise apply:

object Stack {
def apply[A](elems: List[A]) = new StackA
}

// val s = Stack(List(1,2,3))

\2. Use a factory.
http://www.scala-lang.org/api/current/index.html#scala.collection.generic.CanBuildFrom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment