Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created August 31, 2011 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmizu/1184933 to your computer and use it in GitHub Desktop.
Save kmizu/1184933 to your computer and use it in GitHub Desktop.
A Visitor pattern example, which solved "Expression Problem" related to Visitor.
trait VisitorsBase {self =>
trait Node {
def accept(v: V)
}
case class Add(l: Node, r: Node) extends Node {
def accept(v: V) {
v.visit(this)
}
}
case class Sub(l: Node, r: Node) extends Node {
def accept(v: V) {
v.visit(this)
}
}
case class Value(value: Int) extends Node {
def accept(v: V) {
v.visit(this)
}
}
type V <: Visitor
trait Visitor {self: V =>
def visit(node: Add) {
println("Add!")
node.l.accept(this)
node.r.accept(this)
}
def visit(node: Sub) {
println("Sub!")
node.l.accept(this)
node.r.accept(this)
}
def visit(node: Value) {
println("Value: " + node.value)
}
}
}
object VisitorsPlus extends VisitorsBase {
type V = Visitor
case class Mul(l: Node, r: Node) extends Node {
def accept(v: V) {
v.visit(this)
}
}
case class Div(l: Node, r: Node) extends Node {
def accept(v: V) {
v.visit(this)
}
}
class Visitor extends super.Visitor {
def visit(node: Mul) {
println("Mul")
node.l.accept(this)
node.r.accept(this)
}
def visit(node: Div) {
println("Div")
node.l.accept(this)
node.r.accept(this)
}
}
}
object VisitorMain {
import VisitorsPlus._
def main(args: Array[String]) {
val v = new Visitor
Add(Value(1), Value(2)).accept(v)
Sub(Value(1), Value(2)).accept(v)
Mul(Value(1), Value(2)).accept(v)
Div(Value(1), Value(2)).accept(v)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment