2009-02-23 15 views
7

Mi stavo chiedendo, posso decomporre un tipo di tupla nei tipi dei suoi componenti in Scala?Disimballaggio dei tipi di tuple in Scala

Voglio dire, qualcosa di simile

trait Container { 
    type Element 
} 

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

risposta

3

Non si può disfare, di per sé, ma forse questo modo si ottiene ciò che si vuole:

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

Questo è quello che pensavo di dover fare, ma volevo evitare, perché ciò avrebbe cambiato l'implementazione delle classi estendendo questo tratto. – jpalecek

+0

Inoltre, questo significa che la coppia di elementi sarebbe la stessa coppia anche in sottoclassi? Non dovrebbe essere piuttosto Element <: (Primo, Secondo) [o forse anche delimitato più in basso]? – jpalecek

0

Sono un po 'tardi per questo, ma per quanto riguarda l'uso della corrispondenza del modello? Non ha proprio il tipo di ritorno corretta e la mia sintassi potrebbe essere un po 'fuori, ma qui va:

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

Ciò non decomprimere i tipi, ma non vincolare i tipi A e B quando chiamata get .

trait Container { 
    type Element 
} 

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

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

Questo sembra essere molto promettente, ma è barare - che non funziona se Element è astratta.

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 
}