Значение по умолчанию для параметра типа в Scala

Я не могу понять, как (если вообще) вы можете установить значение по умолчанию для параметра типа в Scala.
В настоящее время у меня есть метод, подобный этому:

def getStage[T <: Stage](key: String): T = {
  // Do fancy stuff that returns something
}

Но то, что я хотел бы сделать, это обеспечить реализацию getStage, которая не принимает значения для T и вместо этого использует значение по умолчанию. Я попытался просто определить другой метод и перегрузить параметры, но это только приводит к тому, что один из методов полностью переопределяется другим. Если мне не ясно, что я пытаюсь сделать, это примерно так:

def getStage[T<:Stage = Stage[_]](key: String): T = {

}

Я надеюсь, что это ясно, о чем я прошу. Кто-нибудь знает, как это могло бы быть достигнуто?

Ответ 1

Вы можете делать такие вещи безопасным типом, используя классы типов. Например, предположим, что у вас есть класс этого типа:

trait Default[A] { def apply(): A }

И следующая иерархия типов:

trait Stage
case class FooStage(foo: String) extends Stage
case class BarStage(bar: Int) extends Stage

И в некоторых случаях:

trait LowPriorityStageInstances {
  implicit object barStageDefault extends Default[BarStage] {
    def apply() = BarStage(13)
  }
}

object Stage extends LowPriorityStageInstances {
  implicit object stageDefault extends Default[Stage] {
    def apply() = FooStage("foo")
  }
}

Затем вы можете написать свой метод следующим образом:

def getStage[T <: Stage: Default](key: String): T =
  implicitly[Default[T]].apply()

И он работает следующим образом:

scala> getStage("")
res0: Stage = FooStage(foo)

scala> getStage[BarStage]("")
res1: BarStage = BarStage(13)

Что я думаю, более или менее то, что вы хотите.