Lets say I've a trait with a type A
that is a subclass of Any
and a method called nextState
that has that same type as a parameter.
trait GameEnvironment {
type A <: Any
def nextState(state: A, input: Int): (A, Boolean)
}
This trait is then extended by a class called Tetris
that overrides the type member A
and the method nextState
.
class Tetris extends GameEnvironment {
override type A = ((Array[Array[Int]]), Int)
def nextState(state: (Array[Array[Int]], Int), input: Int):
((Array[Array[Int]], Int), Boolean) = {
((state, false))
}
}
Now in another class called ReinLib
I create a GameEnvironment
, and I also have a function that takes in a parameter GameEnvironment#A
.
class ReinLib(val mode: String) {
val env : GameEnvironment = new Tetris()
def simulateStep(state: GameEnvironment#A, input: Int): (Boolean) =
{
env.nextState(state, input)._2
}
}
Now if I compile this code I get an error
type mismatch state.type (with underlying type...
From what I gather this happens since the compiler is not certain which type state
has. However I could not seem to find how to solve my issue, so I'm wondering how one would get around this.
The type GameEnvironment#A
is way too vague, it is essentially completely unrelated to the type of state used in env
.
You probably want something like this:
trait GameEnvironment {
type A
def nextState(state: A, input: Int): (A, Boolean)
}
class Tetris extends GameEnvironment {
override type A = ((Array[Array[Int]]), Int)
def nextState(state: A, input: Int): (A, Boolean) = {
(state, false)
}
}
class ReinLib(val mode: String) {
val env: GameEnvironment = new Tetris()
def simulateStep(state: env.A, input: Int): Boolean = {
env.nextState(state, input)._2
}
}
It compiles successfully, because now env.nextState
can accept state: env.A
as parameter.