Salim Fadhley Salim Fadhley - 1 month ago 4x
Scala Question

Make a generic trait which requires it's parameterized type to inherit from 2 other traits

I have a working generic trait that's something like this:

trait Container[T <: BaseGameObject] {
val contents = new mutable.HashMap[Int, T]

Containers are objects in my game that can contain other game entities (e.g. bags, rooms).

BaseGameObject is a trait that all of the main kinds of things in my game have to implement.

case class Room(sn: Int, snGenerator: () => Int) extends BaseGameObject with Container[Thing] {

I want to define the main kinds of entity in my game by composing a bunch of traits, some of which will be parameterized. For example, in the above, I am saying that Rooms are BasicGameObjects and also Containers of Things.

But what if I wanted to say that the T in Container has to implement more than one trait. For example, instead of saying

trait Container[T <: BaseGameObject]

I'd like something that means the same as the following pseudocode:

trait Container[T <: (BaseGameObject AND FooEntity)]

And I'd like this to mean that whenever I use a container, I can be sure that T implements both BaseGameObject AND FooEntity.

Is there a syntax for saying that T in my generic trait must implement both?

trait Container[T <: BaseGameObject with FooEntity] 

The with keyword is how a developer mixes traits into other classes. You can mix in any number of traits to any class.