I am trying to use Scala's cake pattern with generic interceptors with multiple groups (layers) of those. When end of one layer needs another layer I try to express that using self type. But it fails with Illegal inheritance. The general context of the task is I have a document model on which I am trying to do chain of validations. Toy example follows with each layer represented by just one trait.
trait Element trait Leaf extends Element trait Composed extends Element trait Validator [A] {def validate (element : A) : String} //second layer trait LeafValidator extends Validator[Leaf]{ override def validate (element : Leaf) : String = "leaf"} //first layer trait ElementValidator extends Validator[Element]{ self : Validator[Leaf] => override def validate (element : Element) : String = element match { case leaf : Leaf => super.validate(leaf) case _ => "other" } } case class Concrete extends LeafValidator with ElementValidator The error is on the instantiation line
illegal inheritance; self-type apltauer.david.util.Concrete does not conform to apltauer.david.util.ElementValidator's selftype apltauer.david.util.ElementValidator with apltauer.david.util.Validator[apltauer.david.util.Leaf] Main.scala /Dependency/src/apltauer/david/util line 56 Scala Problem
Contravariance supresses the error but does not solve the problem as the self type is useless then.