Тип аргумента конструктора класса Case в зависимости от предыдущего значения аргумента

Я пытаюсь сделать следующее

trait Stateful {
  type State
}

case class SystemState(system: Stateful, state: system.State) // does not compile

То есть тип stateзависит от (значение) system, Это, однако, не поддерживается:

недопустимый тип зависимого метода: параметр появляется в типе другого параметра в том же разделе или более раннем

С помощью аргументов функции я мог бы разделить аргументы на два списка аргументов, что невозможно с помощью конструктора класса case:

def f(system: Stateful)(state: system.State): Unit = {} // compiles

Лучшее, что я могу сделать, это:

case class SystemState[S](system: Stateful { type State = S }, state: S) // compiles

но я думал, что это возможно без параметра типа, так как в dotty, я полагаю, параметры типа десагерируются в члены типа.

Мой вопрос тогда, это может быть выражено без параметров типа?

В более общем контексте я исследую, в какой степени параметры типа могут быть заменены членами типа, и когда это хорошая идея.

1 ответ

Решение

Подход со списком нескольких параметров для зависимых типов, к сожалению, не поддерживается для конструкторов, поэтому нет, вам придется вводить параметр типа.

Вы можете скрыть этот факт, если это станет беспокоить, хотя

trait Stateful {
  type State
}

object SystemState {
  def apply(system: Stateful)(state: system.State): SystemState = 
    new Impl[system.State](system, state)

  private case class Impl[S](val system: Stateful { type State = S }, 
                             val state: S)
    extends SystemState {
    override def productPrefix = "SystemState"
  }
}
trait SystemState {
  val system: Stateful
  val state: system.State
}

case object Test extends Stateful { type State = Int }
val x = SystemState(Test)(1234)
Другие вопросы по тегам