2009-02-23 3 views
7

Мне просто интересно, могу ли я разложить тип кортежа на его типы компонентов в Scala?Распаковка типов кортежей в Scala

Я имею в виду, что-то вроде этого

trait Container { 
    type Element 
} 

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

ответ

3

Вы не можете распаковать, сам по себе, но, возможно, это добивается того, чего вы хотите:

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

Это то, что, как я думал, мне нужно было сделать, но хотелось избежать, потому что это изменило бы реализацию классов, расширяющих эту черту. – jpalecek

+0

Кроме того, означает ли это, что пара элементов будет такой же, как и в подклассах? Разве это не будет скорее Элемент <: (Первый, Второй) [или, возможно, нижний ограниченный]? – jpalecek

0

Я немного опоздал с этим, но как насчет использования соответствия шаблону? Не имеет достаточно правильный тип возвращаемого, и мой синтаксис может быть немного прочь, но здесь идет:

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

Это не распаковывает типов, но это не ограничивает типы A и B при призывающих get ,

trait Container { 
    type Element 
} 

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

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

Это выглядит многообещающим, но это обман - это не работает, если Element является абстрактным.

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 
} 
Смежные вопросы