2017-06-29 82 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這應該能夠達到我認爲的相同結果。