2010-08-02 11 views
8

Je veux écrire une conversion implicite de Tuple2 [A, B] Seq [C] où C est super type de A et B. Mon premier essai comme suit:Un problème de conversions implicites dans scala 2.8

implicit def t2seq[A,B,C](t: (A,B))(implicit env: (A,B) <:< (C,C)): Seq[C] = { 
    val (a,b) = env(t) 
    Seq(a,b) 
} 

Mais cela ne fonctionne pas:

scala> (1,2): Seq[Int] 
<console>:7: error: type mismatch; 
found : (Int, Int) 
required: Seq[Int] 
     (1,2): Seq[Int] 
    ^

Alors que celui-ci fonctionne:

class Tuple2W[A,B](t: (A,B)) { 
    def toSeq[C](implicit env: (A,B) <:< (C,C)): Seq[C] = { 
     val (a,b) = env(t) 
     Seq(a,b) 
    } 
} 
implicit def t2tw[A,B](t: (A,B)): Tuple2W[A,B] = new Tuple2W(t) 

utilisation:

scala> (1,2).toSeq 
res0: Seq[Int] = List(1, 2) 

Je ne sais pas pourquoi la première solution n'a pas fonctionné comme prévu. Scala version 2.8.0.r22634-b20100728020027 (machine virtuelle client Java HotSpot (TM), Java 1.6.0_20).

+2

Je pense que les paramètres '<: <' sont généralement appelés 'ev' (abréviation de 'preuve'), et non env. –

Répondre

9

Vous ne devez utiliser <:< si les paramètres à limiter sont déjà consolidés dans le périmètre environnant (comme dans votre deuxième essai), donc dans votre cas

implicit def t2seq[A <: C,B <: C,C](t: (A,B)) = Seq(t._1, t._2) 

est suffisante.

Je suppose que votre premier essai n'a pas fonctionné car il est trop complexe pour l'inferencer de type.