Created
November 13, 2013 23:53
-
-
Save arjunguha/7458697 to your computer and use it in GitHub Desktop.
Script from class
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
// Based on "Independently Extensible Solutions to the Expression Problem" by | |
// by Matthias Zenger and Martin Odersky, from FOOL 2005. | |
// | |
// http://lampwww.epfl.ch/~odersky/papers/ExpressionProblem.html | |
// | |
// I was using Scala 2.10.3 | |
trait Base { | |
trait Exp { | |
def eval(): Int | |
} | |
type exp <: Exp | |
trait Num extends Exp { | |
val n : Int | |
def eval() = n | |
} | |
} | |
trait AddFeature extends Base { | |
trait Add extends Exp { | |
val e1 : exp | |
val e2 : exp | |
def eval() = e1.eval() + e2.eval() | |
} | |
} | |
// @author John | |
trait ShowFeature extends Base { | |
trait Exp extends super.Exp { | |
def show(): String | |
} | |
type exp <: Exp | |
trait Num extends super.Num with Exp { | |
def show() = n.toString | |
} | |
} | |
trait ShowAddFeature extends ShowFeature with AddFeature { | |
trait Add extends super.Add | |
with super[ShowFeature].Exp { | |
def show() = s"${e1.show()} + ${e2.show()}" | |
} | |
} | |
trait PrintFeature extends Base { | |
trait Exp extends super.Exp { | |
def print(): String | |
} | |
type exp <: Exp | |
trait Num extends super.Num with Exp { | |
def print() = s"new Num(${n.toString()})" | |
} | |
} | |
trait PrintAddFeature extends PrintFeature with AddFeature { | |
trait Add extends super.Add | |
with super[PrintFeature].Exp { | |
def print() = s"new Add(${e1.print()}, ${e2.print()})" | |
} | |
} | |
trait BothFeatures extends ShowAddFeature with PrintAddFeature { | |
trait Exp extends super[ShowAddFeature].Exp | |
with super[PrintAddFeature].Exp | |
type exp <: Exp | |
trait Num extends super[ShowAddFeature].Num | |
with super[PrintAddFeature].Num | |
with Exp | |
trait Add extends super[ShowAddFeature].Add | |
with super[PrintAddFeature].Add | |
with Exp | |
} | |
object MyExpHierarchy extends BothFeatures { | |
type exp = Exp | |
def add (x : Exp, y : Exp) = new Add { val e1 = x; val e2 = y } | |
def num (v : Int) = new Num { val n = v } | |
} | |
import MyExpHierarchy._ | |
val e = add(num(200), num(300)) | |
println("Result: " + e.eval()) | |
println("AST: " + e.print()) | |
println("Pretty: " + e.show()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment