I'm trying to return a subclass of a parameterized type Output[T <: Input]
but for some reason I cannot seem to get the syntax right:
sealed trait Input
case class A(id: Int) extends Input
case class B(id: String) extends Input
sealed trait Output[+T <: Input]
case class OutA(some: String) extends Output[A]
case class OutB(thing: Int) extends Output[B]
def doStuff[T <: Input, RT <: Output[T]](input: T): RT =
input match {
case A(i) => OutA(i.toString)
case B(s) => OutB(s.toInt)
}
// error: type mismatch;
// found : OutA
// required: RT
// case A(i) => OutA(i.toString)
//
// error: type mismatch;
// found : OutB
// required: RT
// case B(s) => OutB(s.toInt)
def doStuff[T <: Input](input: T): Output[T] =
input match {
case A(i) => OutA(i.toString)
case B(s) => OutB(s.toInt)
}
// error: type mismatch;
// found : OutA
// required: Output[T]
// case A(i) => OutA(i.toString)
// error: type mismatch;
// found : OutB
// required: Output[T]
// case B(s) => OutB(s.toInt)
def doStuff[T <: Input, RT <: Output[_]](input: T): RT =
input match {
case A(i) => OutA(i.toString)
case B(s) => OutB(s.toInt)
}
// error: type mismatch;
// found : OutA
// required: RT
// case A(i) => OutA(i.toString)
// error: type mismatch;
// found : OutB
// required: RT
// case B(s) => OutB(s.toInt)
In my actual code the Input
and Output
subclasses are wrapped in containers that I cannot modify and the input is also coming from another system over which I have no control. However, this seems to be the smallest example I could come up with for which I get the same compile-time type errors.
How can I solve my problem?