Created
February 26, 2013 11:46
-
-
Save anonymous/5037918 to your computer and use it in GitHub Desktop.
This file contains 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
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