2016-05-09 12 views
2

Ich habe einen Selbst rekursiven Typ:Muster auf generische abstrakte Art in scala passend

trait Problem[P <: Problem[P]] { 
    type Solution 
} 

Jetzt will ich Match Muster auf P#Solution. Nehmen wir an, wir im case class Foo[P <: Problem[P]]() sind:

case ExampleCaseClass(s: P#Solution) if conditionApplies() => 
    // do sth 

case ExampleCaseClass(s: P#Solution) => 
    // now sth else 

Natürlich scheitert es durch Löschen geben. Gibt es eine Möglichkeit, diesen Code in scala zu kompilieren?

Ich habe Klassen-/Typ-Tags gesehen, aber ich bin mir nicht sicher, ob sie in einem solchen Fall verwendet werden können.

Antwort

2

Sie können tatsächlich Typ-Tags verwenden, aber Sie benötigen einen konkreten Typ, um den Typen-Tag zu erhalten.

case class Foo[P <: Problem[P], S <: P#Solution:TypeTag]() { 
    def doSomething[T:TypeTag](c: ExampleCaseClass[T]) = c match { 
    case ExampleCaseClass(s) if typeOf[T] =:= typeOf[S] => "x" 
    case ExampleCaseClass(s) => "y" 
    } 
} 

Wenn Sie einen Subtyp Spiel möchten, verwenden Sie <:< statt =:=: Sie konnten die Lösungstyp als Typ-Parameter hinzuzufügen.

+0

Scheint ein bisschen laut zu sein. Was passiert, wenn ich auch eine Musterung für eine völlig andere Klasse im selben Block erstellen muss? – slnowak

+1

Wenn Sie Typen vergleichen müssen, die durch Löschen eliminiert werden, glaube ich nicht, dass es eine prägnantere Lösung gibt, aber ich würde mich sehr freuen, davon zu hören. – devkat