2017-06-29 9 views
0

何が入っているかに基づいて特定のデータ型を返すことは可能ですか?のは、私は次のコードを持っているとしましょう:TSpecificAと同様にBのためであればスカラの入力パラメータタイプに基づいて戻り値の型を制限する

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することができます。私がすべての「許可された」組み合わせを知っているなら、それを強制する方法はありますか?

答えて

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()) 

これは「入力」(例えばSpecificA)と「出力」(例えばSomeAWithBellsAndWhistles)リンク暗黙のFindThing値を作成することによって動作します許容される各組み合わせのタイプ。これは特定の階層に入力タイプ&が存在する必要がないことに注意してください(例えば、すべての入力タイプはSuperを拡張する必要はありません)。

emulate functional dependenciesでも同じ結果が得られるはずです。

関連する問題