Created
May 4, 2015 06:39
-
-
Save trumanw/5004975a397232524202 to your computer and use it in GitHub Desktop.
Visitors in Scala --- Matching Object With Patterns
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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