Skip to content

Instantly share code, notes, and snippets.

@arjunguha
Created November 13, 2013 23:53
Show Gist options
  • Save arjunguha/7458697 to your computer and use it in GitHub Desktop.
Save arjunguha/7458697 to your computer and use it in GitHub Desktop.
Script from class
// 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