2017-06-29 41 views
0

是否可以根据进入的内容返回特定的数据类型?比方说,我有以下代码:在Scala中根据输入参数类型约束返回类型

sealed trait Super 
case class SpecificA(...) extends Super 
case class SpecificB(...) extends Super 

trait Bells 
trait Whistles 

sealed trait Something 
case class SomeAWithBellsAndWhistles(...) extends Something with Bells with Whistles 
case class SomeBWithBellsAndWhistles(...) extends Something with Bells with Whistles 

object Utils { 
    def doStuff[T <: Super](...): RT 
} 

RT只能是SomeAWithBellsAndWhistles如果TSpecificA,类似的还有B。如果我知道所有'允许'组合,是否有办法强制执行?

回答

2

您是否在寻找参数化类型?

sealed trait Something[T <: Super] 
class SomeAWithBellsAndWhistles extends Something[SomeA] with Bells with Whistles 
class SomeBWithBellsAndWhistles extends Something[SomeB] with Bells with Whistles 

def doStuff[T <: Super](...): Something[T] 
1

您可以使用一个类型级别的功能来实现这一点:

trait FindThing[A] { 
    type Out 
} 
object FindThing { 
    type Aux[A, B] = FindThing[A] { type Out = B } 
    implicit def findA: FindThing.Aux[SpecificA, SomeAWithBellsAndWhistles] = 
    new FindThing[SpecificA] { 
     type Out = SomeAWithBellsAndWhistles 
    } 
    implicit def findB: FindThing.Aux[SpecificB, SomeBWithBellsAndWhistles] = 
    new FindThing[SpecificB] { 
     type Out = SomeBWithBellsAndWhistles 
    } 
} 

def doStuff[T](t: T)(implicit T: FindThing[T]): T.Out = 
    ??? 

def x: SomeAWithBellsAndWhistles = doStuff(SpecificA()) 
def y: SomeBWithBellsAndWhistles = doStuff(SpecificB()) 

这是通过创建一个隐含的FindThing值链接的“输入”(例如,SpecificA)和“输出”(例如,SomeAWithBellsAndWhistles)类型为每个允许的组合。请注意,这不需要输入&特定层次结构中存在的输出类型(例如,所有输入类型不需要扩展Super)。

你也可以emulate functional dependencies这应该能够达到我认为的相同结果。