Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created January 12, 2012 14:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmizu/1600791 to your computer and use it in GitHub Desktop.
Save kmizu/1600791 to your computer and use it in GitHub Desktop.
A Visitor pattern example, which solved "Expression Problem".
trait Visitors {
type V <: Visitor
type E <: Expression
trait Visitor {
def visit(e: Addition): Int
def visit(e: Subtraction): Int
def visit(e: Multiplication): Int
def visit(e: Num): Int
}
trait Expression {
def accept(v: V): Int
}
case class Addition(l: E, r: E) extends Expression {
def accept(v: V): Int = {
v.visit(this)
}
}
case class Subtraction(l: E, r: E) extends Expression {
def accept(v: V): Int = {
v.visit(this)
}
}
case class Multiplication(l: E, r: E) extends Expression {
def accept(v: V): Int = {
v.visit(this)
}
}
case class Num(v: Int) extends Expression {
def accept(v: V): Int = {
v.visit(this)
}
}
}
object ExtendedVisitors extends Visitors {
type V = Visitor
type E = Expression
trait Visitor extends super.Visitor {
def visit(e: Division): Int
}
case class Division(l: E, r: E) extends Expression {
def accept(v: V): Int = {
v.visit(this)
}
}
object Calculator extends Visitor {
def visit(e: Addition): Int = e.l.accept(this) + e.r.accept(this)
def visit(e: Subtraction): Int = e.l.accept(this) - e.r.accept(this)
def visit(e: Multiplication): Int = e.l.accept(this) * e.r.accept(this)
def visit(e: Division): Int = e.l.accept(this) / e.r.accept(this)
def visit(e: Num): Int = e.v
}
def main(args: Array[String]) {
val exp = Addition(Num(2), Division(Num(4), Num(2)))
println(exp.accept(Calculator)) // 4
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment