Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Scala traits to be incompatible

Is there a way to stop two traits from being mixed into a class together?

I know you can use self type annotations to require that a trait only be mixed into a class of a specific type, but can you use a similar construct to require that the target class NOT mix in a specific trait?

For example:

abstract class Collector(p: Boolean)

trait Cache

trait ACache extends Cache { self: Collector => }

trait BCache extends Cache { self: Collector => }

Can I require that any implementation of Collector mix in ACache, BCache, or no cache trait whatsoever, but not ACache and BCache simultaneously?

class GoodCollector(p: Boolean) extends Collector(p) with ACache //legal
class BadCollector(p: Boolean) extends Collector(p) with ACache with BCache //illegal
like image 419
D Cohen Avatar asked Mar 04 '23 19:03

D Cohen


1 Answers

If you change your Cache like this:

trait Cache[A <: Cache[_]]

trait ACache extends Cache[ACache] { self: Collector =>
}

trait BCache extends Cache[BCache] { self: Collector =>
}

then:

class BadCollector(p: Boolean) extends Collector(p) with ACache with BCache 

will fail with:

illegal inheritance; class BadCollector inherits different type instances of trait Cache: Cache[BCache] and Cache[ACache] class BadCollector(p: Boolean) extends Collector(p) with ACache with BCache

like image 153
Krzysztof Atłasik Avatar answered Mar 06 '23 19:03

Krzysztof Atłasik