返回参数化类型的子类斯卡拉
问题描述:
我试图返回一个参数化类型Output[T <: Input]
的一个子类,但由于某种原因,我似乎无法得到语法正确:返回参数化类型的子类斯卡拉
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)
在我实际的代码Input
和Output
子类被封装在容器中,我无法修改,输入也来自另一个我无法控制的系统。然而,这似乎是我能想到的最小的例子,我得到相同的编译时类型错误。
我该如何解决我的问题?
答
你可以这样来做(这是Scala中的一个type class的例子,搜索这个词会给你不少的帖子解释模式):
case class StuffDoer[T](doStuff: T => Output[T])
object StuffDoer {
implicit val ADoer: StuffDoer[A] = StuffDoer(x => OutA(x.id.toString))
implicit val BDoer: StuffDoer[B] = StuffDoer(x => OutB(x.id.toInt))
implicit val InputDoer: StuffDoer[Input] = StuffDoer {
case a: A => ADoer.doStuff(a)
case b: B => BDoer.doStuff(b)
}
}
def doStuff[T](input: T)(implicit doer: StuffDoer[T]) = doer.doStuff(input)
(说真的,有些变化这个问题会不时问到,但是写出答案比搜索以前的问题要快。)