2016-03-16 71 views
0

我想写一个类型类来staticly编码有什么我可以输出到PrinterScala的类型类派生的集合

import java.io.PrintWriter 

    trait Write[A] { 
    def apply(out: PrintWriter)(x: A): Unit 
    } 
    object Write { 
    def apply[A] = new Write[A] { 
     def apply(out: PrintWriter)(x: A) = out.print(x) 
    } 
    implicit val string  : Write[String]  = Write[String] 
    implicit val char  : Write[Char]  = Write[Char] 
    implicit val boolean : Write[Boolean] = Write[Boolean] 
    implicit val int  : Write[Int]  = Write[Int] 
    implicit val long  : Write[Long]  = Write[Long] 
    implicit val bigInt  : Write[BigInt]  = Write[BigInt] 
    implicit val double  : Write[Double]  = Write[Double] 
    implicit val bigDecimal : Write[BigDecimal] = Write[BigDecimal]  
    } 

现在我可以这样写:

def output[A(out: PrintWriter, x: A)(implicit write: Write[A]) = write(out)(x) 

output(out, "hello") // compiles 
output(out, 1) //compiles 
output(out, Set.empty[String]) // does not compile 

但是,现在我想写一个Write所有Iterable S:

implicit def iterable[A](implicit write: Write[A]) = new Write[Iterable[A]] { 
     def apply(out: PrintWriter)(xs: Iterable[A]) = { 
     xs.foreach(write(out)) 
     out.println() 
     } 
    } 

但是,我还是不能编译如下:理想情况下

output(out, Set.empty[String]) // should compile!! 

,我应该能够导出嵌套iterables太例如: -

output(out, Array.ofDim[Int](100, 100)) // should compile!! 

我该怎么办?我查看了CanBuild,但是在构建集合时这很有用;在这种情况下,我正在解构一个集合。

+1

好了,你的'Write'是不变的,这编译'输出(出,Set.empty [String] .toIterable)' –

+0

Doh!我以为我有它:) – pathikrit

回答

2

你可以声明类型参数的特质写被逆变像这样:

trait Write[-A] { 
    def apply(out: PrintWriter)(x: A): Unit 
} 

,然后这应该编译