根据Scala中的输入参数类型约束返回类型

时间:2017-06-29 14:58:13

标签: 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
}
如果RTSomeAWithBellsAndWhistles,则{p> T只能为SpecificA,对B也类似。如果我知道所有'允许'的组合,有没有办法强制执行?

2 个答案:

答案 0 :(得分: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 :(得分: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值来实现。请注意,这并不需要输入&amp;特定层次结构中存在的输出类型(例如,所有输入类型都不需要扩展Super)。

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

相关问题