2015-03-13 28 views
14

próbuję zrobić następująceCase typ argumentu konstruktora klasy w zależności od poprzedniej wartości argumentu

trait Stateful { 
    type State 
} 

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

to znaczy rodzaj state zależy (wartość) system. To jednak nie jest obsługiwany:

nielegalne zależne od typu metoda: parametr pojawia się w rodzaju innego parametru w tej samej sekcji lub wcześniejszego jednego

z argumentami funkcji, mogę podzielić argumenty na dwie listy argumentów, co nie jest możliwe przy użyciu konstruktora klasy obudowy:

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

najlepsze co mogę zrobić to:

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

ale myślałem, że powinno być możliwe bez parametru typu, ponieważ w dotty, przypuszczam, że parametry typu są desugared do członków typu.

Moje pytanie brzmi: czy można to wyrazić bez parametrów typu?

W bardziej ogólnym kontekście zastanawiam się, w jakim stopniu parametry typu mogą być zastąpione przez członków typu, a kiedy to jest dobry pomysł, aby to zrobić.

Odpowiedz

8

Podejście wielu parametrów dla typów zależnych to niestety not supported for constructors, więc nie, trzeba będzie wprowadzić parametr typu.

Można ukryć ten fakt, jeśli staje się kłopotliwy, choć

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)