5

Ich habe einen F-begrenzt Typen Sys:Existentielle Typ oder Typ gebunden Parameterfehler

trait Sys[S <: Sys[S]] 

und einige Eigenschaft, die es als Typ-Parameter übernehmen:

trait Foo[S <: Sys[S]] 

Angenommen, ich habe eine Methode zu sein, aufgerufen mit einem Foo:

def invoke[S <: Sys[S]](foo: Foo[S]) =() 

nehme ich ein Modell Update-Typ haben, ein da Untertypen, die trägt ein Foo:

sealed trait Update 
case class Opened[S <: Sys[S]](foo: Foo[S]) extends Update 

eine Hilfsfunktion ein Modell Beobachter registrieren:

def observe(pf: PartialFunction[Update, Unit]) =() 

nun folgende fehlschlägt:

observe { 
    case Opened(foo) => invoke(foo) 
} 

mit

<console>:16: error: inferred type arguments [Any] do not conform to method invoke's 
        type parameter bounds [S <: Sys[S]] 
       case Opened(foo) => invoke(foo) 
            ^

Wie kann ich fix die Teilfunktion, wenn Sys, Foo, invoke, Update, Opened und observe gegeben. Es ist erlaubt, einen Wert oder Typ Mitglied Foo hinzuzufügen.

Antwort

0

Eine mögliche Lösung ist Gießen:

observe { 
    case Opened(foo) => invoke(foo.asInstanceOf[Foo[~] forSome { type ~ <: Sys[~] }]) 
} 

Offensichtlich ist schrecklich und nicht die bevorzugte Lösung, so dass ich für andere Antworten warte.

1

Wie über Parameter Bewegungstyp für Foo Eigenschaft Variable Typ:

trait Sys[S <: Sys[S]] 
trait Foo { type S <: Sys[S] } 

sealed trait Update 
case class Opened(foo: Foo) extends Update 

def invoke(foo: Foo) =() 
def observe(pf: PartialFunction[Update, Unit]) =() 

observe { 
    case Opened(foo) => invoke(foo) 
} 

Update:

Sie sind absolut richtig. Und für alle neuen Typen müssen Sie den Alias ​​für den Bewegungstyp-Parameter in body definieren.

Typ alias Beispiel:

trait Sys[S <: Sys[S]] 
class A extends Sys[A] 
class B extends Sys[B] 

trait Foo { type S <: Sys[S] } 
trait Boo { type S <: Sys[S] } 

object module_A{ 
    type Foo = com.company.Foo { type S <: A } 
    type Boo = com.company.Boo { type S <: A } 
} 

def invoke(foo: module_A.Foo, boo: module_A.Boo) =()   
+0

Das Problem ist, diese sofort ermüdend werden, wird meine ganze API auf einem Typkonstruktor Parameter basiert. Sie haben bald 'def foo [S1 <: Sys [S1]] (Balken: Balken {Typ S = S1}, baz: Baz {Typ S = S1}): Gaga {Typ S = S1} usw. –