2009-02-23 6 views
7

Je me demandais juste si je pouvais décomposer un type de ligne en types Scala?Déballage de types de lignes dans Scala

Je veux dire, quelque chose comme ça

trait Container { 
    type Element 
} 

trait AssociativeContainer extends Container { 
    type Element <: (Unit, Unit) 
    def get(x : Element#First) : Element#Second 
} 

Répondre

3

Vous ne pouvez pas déballer, en soi, mais peut-être ce que vous voulez réalise:

type First 
    type Second 
    type Element = (First, Second) 
    def get(x: First): Second 
+0

C'est ce que je pensais avoir besoin de faire, mais que je voulais éviter, car cela changerait l'implémentation des classes prolongeant ce trait. – jpalecek

+0

Aussi, cela signifie-t-il que la paire d'éléments serait la même paire même dans les sous-classes? Ne devrait-il pas plutôt être Element <: (First, Second) [ou peut-être plus bas, aussi]? – jpalecek

0

Je suis un peu en retard à cela, mais qu'en est-il de l'utilisation de la correspondance de modèle? N'a pas tout à fait le type de retour correct, et ma syntaxe pourrait être un peu loin, mais va ici:

def get[K](key: K): Iterable[Any] { 
    for ((key, x) <- elements) yield x 
} 
3

Cela ne déballez pas les types, mais il ne limite les types A et B lors de l'appel get .

trait Container { 
    type Element 
} 

trait AssociativeContainer extends Container { 
    type Element <: Tuple2[_, _] 

    def get[A, B](x: A)(implicit ev: (A, B) =:= Element): B 
} 

Cela semble prometteur, mais triche - il ne fonctionne pas si Element est abstraite.

def Unpack[T<:Tuple2[_, _]] = new { 
    def apply[A, B](implicit ev: T <:< (A, B)) = new { 
    type AA = A 
    type BB = B 
    } 
} 

trait AssociativeContainer { 
    type Element = (Int, String) 
    val unpacked = Unpack[Element].apply 
    type A = unpacked.AA 
    type B = unpacked.BB 

    1: A 
    "": B 
    def get(x: A): B 
} 
Questions connexes