2010-08-02 25 views
8

Tôi muốn viết chuyển đổi ngầm Tuple2 [A, B] thành Seq [C] trong đó C là siêu loại của cả A và B. Lần thử đầu tiên của tôi như sau:Vấn đề chuyển đổi ẩn trong 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) 
} 

Nhưng nó không hoạt động:

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

Trong khi người ta này hoạt động:

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) 

Sử dụng trường hợp:

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

Tôi không biết tại sao giải pháp đầu tiên không hoạt động như mong đợi. Phiên bản Scala 2.8.0.r22634-b20100728020027 (Máy khách Java HotSpot (TM), Java 1.6.0_20).

+2

Tôi nghĩ rằng thông số '<: <' thường được gọi là 'ev' (viết tắt của 'bằng chứng'), chứ không phải env. –

Trả lời

9

Bạn chỉ cần sử dụng <:< nếu các thông số bị hạn chế đã được ràng buộc trong phạm vi xung quanh (như trong thử thứ hai của bạn), vì vậy trong trường hợp của bạn

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

là đủ.

Tôi đoán rằng lần thử đầu tiên của bạn không hoạt động vì quá phức tạp đối với trình inferencer loại.

Các vấn đề liên quan