I am writing a generic FSM library:
import scala.annotation.tailrec
trait State {
def isAcceptState: Boolean
}
trait FSM[T <: FSM[T, A, S], -A, +S <: State] { this: T =>
def state: S
def resume(input: A): T
}
object FSM {
@tailrec
def resumeUntilAccept[T <: FSM[T, A, S], A, S <: State](fsm: T, inputs: Iterator[A]): T = {
if (inputs.hasNext) {
val input = inputs.next
val newFSM = fsm.resume(input)
if (newFSM.state.isAcceptState) {
newFSM
} else {
resumeUntilAccept[T, A, S](newFSM, inputs) // THIS LINE OF CODE
}
} else {
throw new Exception("not enough inputs")
}
}
}
If I remove the type argument list on the line marked // THIS LINE OF CODE, I get the following error:
Main.scala:22: error: inferred type arguments
[T,A,Nothing]do not conform to methodresumeUntilAccept's type parameter bounds[T <: FSM[T,A,S],A,S <: State]resumeUntilAccept(newFSM, inputs) ^
Why is Nothing inferred instead of S? And even then, why does it not conform? Nothing is clearly a subtype of State.