public
Created

  • Download Gist
copy_with_traits.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
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)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.