Skip to content

Instantly share code, notes, and snippets.

Created February 26, 2013 11:46
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 anonymous/5037918 to your computer and use it in GitHub Desktop.
Save anonymous/5037918 to your computer and use it in GitHub Desktop.
abstract class A {
type Self <: A
def x: Any
def copy(): Self = {
val copy = construct()
copyStateTo(copy)
copy
}
protected def construct(): Self
protected def copyStateTo(obj: Self) {}
override def toString = s"A(x = $x)"
}
abstract class IntA extends A {
type Self <: IntA
override def x: Int
override def toString = s"IntA(x = $x)"
}
abstract class StringA extends A {
type Self <: StringA
override def x: String
override def toString = s"StringA(x = $x)"
}
case class B(x: Int) extends IntA {
type Self = B
protected def construct() = B(x)
override def toString = s"B(x = $x)"
}
trait T1 extends A {
type Self <: T1
var foo = 0
def incFoo() {
foo = foo + 1
}
override def copyStateTo(obj: Self) {
super.copyStateTo(obj)
obj.foo = foo
}
override def toString = s"${super.toString}\n with T1(foo = $foo)"
}
trait T2 extends A {
type Self <: T2
var bar = 0.9
def squareBar() {
bar = bar * bar
}
override def copyStateTo(obj: Self) {
super.copyStateTo(obj)
obj.bar = bar
}
override def toString = s"${super.toString}\n with T2(bar = $bar)"
}
class IntAWithT1(val x: Int) extends IntA with T1 {
type Self = IntAWithT1
override def construct() = new IntAWithT1(x)
}
class StringAWithT2WithT1(val x: String) extends StringA with T2 with T1 {
type Self = StringAWithT2WithT1
override def construct() = new StringAWithT2WithT1(x)
}
val b = new B(-1)
val iat1 = new IntAWithT1(10)
val sat2t1 = new StringAWithT2WithT1("str")
println(b)
// B(x = -1)
println(iat1)
// IntA(x = 10)
// with T1(foo = 0)
println(sat2t1)
// StringA(x = str)
// with T2(bar = 0.9)
// with T1(foo = 0)
iat1.incFoo()
sat2t1.squareBar()
sat2t1.incFoo()
sat2t1.squareBar()
sat2t1.incFoo()
println(iat1)
// IntA(x = 10)
// with T1(foo = 1)
println(sat2t1)
// StringA(x = str)
// with T2(bar = 0.6561000000000001)
// with T1(foo = 2)
val bC: IntA = b.copy()
println(b)
// B(x = -1)
val iat1C: IntA with T1 = iat1.copy()
println(iat1C)
// IntA(x = 10)
// with T1(foo = 1)
val sat2t1C: StringA with T2 with T1 = sat2t1.copy()
// println(sat2t1C)
// with T2(bar = 0.6561000000000001)
// with T1(foo = 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment