Skip to content

Instantly share code, notes, and snippets.

@davidallsopp
Created November 5, 2013 16:41
Show Gist options
  • Save davidallsopp/7321930 to your computer and use it in GitHub Desktop.
Save davidallsopp/7321930 to your computer and use it in GitHub Desktop.
Linearization of traits in Scala to handle the diamond inheritance problem. Adapted from http://jim-mcbeath.blogspot.co.uk/2009/08/scala-class-linearization.html It now seems OK to refer to indirect parent traits, i.e. super[A], which apparently wasn't possible at the time of the original article.
// Adapted from http://jim-mcbeath.blogspot.co.uk/2009/08/scala-class-linearization.html
object diamond {
class A { def t = 1 }
// super refers to the next trait in the linearization, not necessarily to A
trait B extends A { override def t = super.t + 1 }
trait C extends A { override def t = super.t * 2 }
// Linearises to (D1, C, B, A)
class D0 extends B with C
class D1 extends B with C { override def t = super.t } // C
class D2 extends B with C { override def t = super[A].t }
class D3 extends B with C { override def t = super[B].t }
class D4 extends B with C { override def t = super[C].t }
class D5 extends B with C { override def t = 5 }
// Linearises to (D1, B, C, A)
class E0 extends C with B
class E1 extends C with B { override def t = super.t } // B
class E2 extends B with C { override def t = super[A].t }
class E3 extends C with B { override def t = super[B].t }
class E4 extends C with B { override def t = super[C].t }
class E5 extends C with B { override def t = 5 }
println((new D0).t) //> 4
println((new D1).t) //> 4
println((new D2).t) //> 1
println((new D3).t) //> 2
println((new D4).t) //> 4
println((new D5).t) //> 5
println((new E0).t) //> 3
println((new E1).t) //> 3
println((new E2).t) //> 1
println((new E3).t) //> 3
println((new E4).t) //> 2
println((new E5).t) //> 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment