Skip to content

Instantly share code, notes, and snippets.

@trumanw
Created May 4, 2015 06:39
Show Gist options
  • Select an option

  • Save trumanw/5004975a397232524202 to your computer and use it in GitHub Desktop.

Select an option

Save trumanw/5004975a397232524202 to your computer and use it in GitHub Desktop.
Visitors in Scala --- Matching Object With Patterns
// Cited from the essay "Matching Object With Patterns"
// Class hierarchy:
trait Visitor[T] {
def caseMul(t: Mul): T = otherwise(t)
def caseNum(t: Num): T = otherwise(t)
def caseVar(t: Var): T = otherwise(t)
def otherwise(t: Expr): T = throw new NullPointerException
}
trait Expr {
def matchWith[T](v: Visitor[T]): T
}
class Num(val value: Int) extends Expr {
def matchWith[T](v: Visitor[T]): T = v.caseNum(this)
}
class Var(val name: String) extends Expr {
def matchWith[T](v: Visitor[T]): T = v.caseVar(this)
}
class Mul(val left: Expr, val right: Expr) extends Expr {
def matchWith[T](v: Visitor[T]): T = v.caseMul(this)
}
object Visitors extends App {
val numObj = new Num(1)
val varObj = new Var("var")
val mulObj = new Mul(numObj, varObj)
// Simplification rule:
mulObj.matchWith {
new Visitor[Expr] {
override def caseMul(m: Mul) =
m.left.matchWith {
new Visitor[Expr] {
override def caseNum(n: Num) =
if (1 == n.value) {
println("The left Expr of the mul is : " + n.value)
m.left
} else {
mulObj
}
override def otherwise(e: Expr) = {
println("The left Expr of the mul is not a number")
e
}
}
}
override def otherwise(e: Expr) = {
println("The object is not a mul.")
e
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment