返回参数化类型的子类斯卡拉

问题描述:

我试图返回一个参数化类型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) 

在我实际的代码InputOutput子类被封装在容器中,我无法修改,输入也来自另一个我无法控制的系统。然而,这似乎是我能想到的最小的例子,我得到相同的编译时类型错误。

我该如何解决我的问题?

你可以这样来做(这是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) 

(说真的,有些变化这个问题会不时问到,但是写出答案比搜索以前的问题要快。)